Use new iso resource allocation ioctls
This allows raw1394_bandwidth_modify() and raw1394_channel_modify() to work on juju without write access to the IRM's character device file. If either the build-time requirement of firewire-cdev header ABI >= v.2 or the runtime requirement of firewire-core ABI >= v.2 is not satisfied, the code falls back to transactions to the IRM as before. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
This commit is contained in:
parent
da5156af5a
commit
c58e16442b
|
@ -541,7 +541,10 @@ int raw1394_bandwidth_modify (raw1394handle_t handle, unsigned int bandwidth,
|
|||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return ieee1394_bandwidth_modify(handle, bandwidth, mode);
|
||||
if (handle->is_fw)
|
||||
return fw_bandwidth_modify(handle, bandwidth, mode);
|
||||
else
|
||||
return ieee1394_bandwidth_modify(handle, bandwidth, mode);
|
||||
}
|
||||
|
||||
int raw1394_channel_modify (raw1394handle_t handle, unsigned int channel,
|
||||
|
@ -551,7 +554,10 @@ int raw1394_channel_modify (raw1394handle_t handle, unsigned int channel,
|
|||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return ieee1394_channel_modify(handle, channel, mode);
|
||||
if (handle->is_fw)
|
||||
return fw_channel_modify(handle, channel, mode);
|
||||
else
|
||||
return ieee1394_channel_modify(handle, channel, mode);
|
||||
}
|
||||
|
||||
int raw1394_iso_xmit_init(raw1394handle_t handle,
|
||||
|
|
95
src/fw.c
95
src/fw.c
|
@ -294,6 +294,13 @@ handle_device_event(raw1394handle_t handle,
|
|||
ac = u64_to_ptr(u->request.closure);
|
||||
return ac->callback(handle, ac, &u->request, i);
|
||||
|
||||
#ifdef FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED /* added in kernel 2.6.30 */
|
||||
case FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED:
|
||||
case FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED:
|
||||
memcpy(u64_to_ptr(u->iso_resource.closure), u,
|
||||
sizeof u->iso_resource);
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
case FW_CDEV_EVENT_ISO_INTERRUPT:
|
||||
/* Never happens. */
|
||||
|
@ -631,6 +638,7 @@ int fw_set_port(fw_handle_t handle, int port)
|
|||
handle->local_device = &handle->devices[i];
|
||||
|
||||
handle->generation = reset.generation;
|
||||
handle->abi_version = get_info.version;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -1324,3 +1332,90 @@ fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE /* added in kernel 2.6.30 */
|
||||
|
||||
static int
|
||||
iso_resource_modify(raw1394handle_t handle, unsigned int bandwidth,
|
||||
int channel, enum raw1394_modify_mode mode)
|
||||
{
|
||||
fw_handle_t fwhandle = handle->mode.fw;
|
||||
struct fw_cdev_allocate_iso_resource resource;
|
||||
struct fw_cdev_event_iso_resource event;
|
||||
int ioctl_nr;
|
||||
int err;
|
||||
|
||||
if (channel > 63) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
event.closure = 0;
|
||||
event.channel = -1;
|
||||
event.bandwidth = 0;
|
||||
|
||||
resource.closure = ptr_to_u64(&event);
|
||||
resource.channels = channel >= 0 ? 1ULL << channel : 0;
|
||||
resource.bandwidth = bandwidth;
|
||||
|
||||
ioctl_nr = mode == RAW1394_MODIFY_ALLOC ?
|
||||
FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE :
|
||||
FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE_ONCE;
|
||||
|
||||
err = ioctl(fwhandle->ioctl_fd, ioctl_nr, &resource);
|
||||
|
||||
while (err >= 0 && event.closure != resource.closure)
|
||||
err = fw_loop_iterate(handle);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if ((channel >= 0 && event.channel < 0) ||
|
||||
(bandwidth > 0 && event.bandwidth == 0)) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int abi_v2_available(raw1394handle_t handle)
|
||||
{
|
||||
return handle->mode.fw->abi_version >= 2;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline int
|
||||
iso_resource_modify(raw1394handle_t handle, unsigned int bandwidth,
|
||||
int channel, enum raw1394_modify_mode mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int abi_v2_available(raw1394handle_t handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE) */
|
||||
|
||||
int
|
||||
fw_bandwidth_modify(raw1394handle_t handle, unsigned int bandwidth,
|
||||
enum raw1394_modify_mode mode)
|
||||
{
|
||||
if (abi_v2_available(handle))
|
||||
return iso_resource_modify(handle, bandwidth, -1, mode);
|
||||
else
|
||||
return ieee1394_bandwidth_modify(handle, bandwidth, mode);
|
||||
}
|
||||
|
||||
int
|
||||
fw_channel_modify(raw1394handle_t handle, unsigned int channel,
|
||||
enum raw1394_modify_mode mode)
|
||||
{
|
||||
if (abi_v2_available(handle))
|
||||
return iso_resource_modify(handle, 0, channel, mode);
|
||||
else
|
||||
return ieee1394_channel_modify(handle, channel, mode);
|
||||
}
|
||||
|
|
7
src/fw.h
7
src/fw.h
|
@ -81,6 +81,7 @@ struct fw_handle {
|
|||
int port_count;
|
||||
int err;
|
||||
int generation;
|
||||
int abi_version;
|
||||
void *userdata;
|
||||
int notify_bus_reset;
|
||||
|
||||
|
@ -202,6 +203,12 @@ int fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom,
|
|||
int fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
||||
size_t buffersize, size_t *rom_size,
|
||||
unsigned char *rom_version);
|
||||
int fw_bandwidth_modify(raw1394handle_t handle,
|
||||
unsigned int bandwidth,
|
||||
enum raw1394_modify_mode mode);
|
||||
int fw_channel_modify(raw1394handle_t handle,
|
||||
unsigned int channel,
|
||||
enum raw1394_modify_mode mode);
|
||||
|
||||
int fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle,
|
||||
int prebuffer_packets);
|
||||
|
|
Reference in New Issue