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;
|
errno = EINVAL;
|
||||||
return -1;
|
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,
|
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;
|
errno = EINVAL;
|
||||||
return -1;
|
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,
|
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);
|
ac = u64_to_ptr(u->request.closure);
|
||||||
return ac->callback(handle, ac, &u->request, i);
|
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:
|
default:
|
||||||
case FW_CDEV_EVENT_ISO_INTERRUPT:
|
case FW_CDEV_EVENT_ISO_INTERRUPT:
|
||||||
/* Never happens. */
|
/* Never happens. */
|
||||||
|
@ -631,6 +638,7 @@ int fw_set_port(fw_handle_t handle, int port)
|
||||||
handle->local_device = &handle->devices[i];
|
handle->local_device = &handle->devices[i];
|
||||||
|
|
||||||
handle->generation = reset.generation;
|
handle->generation = reset.generation;
|
||||||
|
handle->abi_version = get_info.version;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -1324,3 +1332,90 @@ fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
||||||
|
|
||||||
return 0;
|
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 port_count;
|
||||||
int err;
|
int err;
|
||||||
int generation;
|
int generation;
|
||||||
|
int abi_version;
|
||||||
void *userdata;
|
void *userdata;
|
||||||
int notify_bus_reset;
|
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,
|
int fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
||||||
size_t buffersize, size_t *rom_size,
|
size_t buffersize, size_t *rom_size,
|
||||||
unsigned char *rom_version);
|
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 fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle,
|
||||||
int prebuffer_packets);
|
int prebuffer_packets);
|
||||||
|
|
Reference in New Issue