/* * AdressRangeMapping REGISTERING: * start, length .... identifies addressrange * *initial_value ... pointer to buffer containing (if necessary) initial value * NULL means undefined * arm_tag .......... identifier for arm_tag_handler * (usually pointer to raw1394_arm_reqhandle) * access_rights .... access-rights for registered addressrange handled * by kernel-part. Value is one or more binary or of the * following flags: ARM_READ, ARM_WRITE, ARM_LOCK * notification_options ... identifies for which type of request you want * to be notified. Value is one or more binary or of the * following flags: ARM_READ, ARM_WRITE, ARM_LOCK * client_transactions ... identifies for which type of request you want * to handle the request by the client application. * for those requests no response will be generated, but * has to be generated by the application. * Value is one or more binary or of the * following flags: ARM_READ, ARM_WRITE, ARM_LOCK * For each bit set here, notification_options and * access_rights will be ignored. * returnvalue: 0 ... success * <0 ... failure */ int ieee1394_arm_register(struct ieee1394_handle *handle, nodeaddr_t start, size_t length, byte_t *initial_value, octlet_t arm_tag, arm_options_t access_rights, arm_options_t notification_options, arm_options_t client_transactions) { int retval=0; struct raw1394_request req; if (((start & ~(0xFFFFFFFF)) != 0) || (((start + length) & ~(0xFFFFFFFF)) != 0)) { errno = EINVAL; return (-1); } CLEAR_REQ(&req); req.type = RAW1394_REQ_ARM_REGISTER; req.generation = handle->generation; /* not necessary */ req.address = start; req.length = length; req.tag = arm_tag; req.recvb = ptr2int(handle->buffer); /* arm_handle on success */ req.misc = ((client_transactions & 0x0f) << 8)|((notification_options & 0x0F) << 4)|(access_rights & 0x0F) |((ARM_REC_LENGTH & 0xFFFF) << 16); req.sendb = ptr2int(initial_value); retval = (int) write(handle->fd, &req, sizeof(req)); return (retval == sizeof(req)) ? 0:-1; }
static unsigned int init_rawdevice(struct ieee1394_handle *h) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_INITIALIZE; req.misc = RAW1394_KERNELAPI_VERSION; h->protocol_version = RAW1394_KERNELAPI_VERSION; if (write(h->fd, &req, sizeof(req)) < 0) return -1; if (read(h->fd, &req, sizeof(req)) < 0) return -1; if (req.error == RAW1394_ERROR_COMPAT && req.misc == 3) { h->protocol_version = 3; if (write(h->fd, &req, sizeof(req)) < 0) return -1; if (read(h->fd, &req, sizeof(req)) < 0) return -1; } if (req.error) { errno = EPROTO; return -1; } memset(h->buffer, 0, HBUF_SIZE); return req.generation; }
int ieee1394_set_port(struct ieee1394_handle *handle, int port) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_SET_CARD; req.generation = handle->generation; req.misc = port; if (write(handle->fd, &req, sizeof(req)) < 0) return -1; if (read(handle->fd, &req, sizeof(req)) < 0) return -1; switch (req.error) { case RAW1394_ERROR_GENERATION: handle->generation = req.generation; errno = ESTALE; return -1; case RAW1394_ERROR_INVALID_ARG: errno = EINVAL; return -1; case RAW1394_ERROR_NONE: if (handle->protocol_version == 3) { handle->num_of_nodes = req.misc & 0xffff; handle->local_id = req.misc >> 16; } else {
int ieee1394_get_port_info(struct ieee1394_handle *handle, struct raw1394_portinfo *pinf, int maxports) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_LIST_CARDS; req.generation = handle->generation; /* IMPORTANT: raw1394 will be writing directly into the memory you provide in pinf. The viability of this approach assumes that the structure of libraw1394's raw1394_portinfo and the kernel's raw1394_khost_list structs are the same!! */ req.recvb = ptr2int(pinf); req.length = sizeof(struct raw1394_portinfo) * maxports; while (1) { if (write(handle->fd, &req, sizeof(req)) < 0) return -1; if (read(handle->fd, &req, sizeof(req)) < 0) return -1; if (!req.error) break; if (req.error == RAW1394_ERROR_GENERATION) { handle->generation = req.generation; continue; } return -1; } return req.misc; }
static int do_iso_listen(struct raw1394_handle *handle, int channel) { struct sync_cb_data sd = { 0, 0 }; struct raw1394_reqhandle rh = { (req_callback_t)_raw1394_sync_cb, &sd }; int err; struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_ISO_LISTEN; req.generation = handle->generation; req.misc = channel; req.tag = ptr2int(&rh); req.recvb = ptr2int(handle->buffer); req.length = HBUF_SIZE; err = write(handle->fd, &req, sizeof(req)); while (!sd.done) { if (err < 0) return err; err = raw1394_loop_iterate(handle); } switch (sd.errcode) { case RAW1394_ERROR_ALREADY: errno = EALREADY; return -1; case RAW1394_ERROR_INVALID_ARG: errno = EINVAL; return -1; default: errno = 0; return sd.errcode; } }
/* * AdressRangeMapping UNREGISTERING: * start ............ identifies addressrange for unregistering * (value of start have to be the same value * used for registering this adressrange) * returnvalue: 0 ... success * <0 ... failure */ int ieee1394_arm_unregister (struct ieee1394_handle *handle, nodeaddr_t start) { int retval; struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_ARM_UNREGISTER; req.generation = handle->generation; /* not necessary */ req.address = start; retval = write(handle->fd, &req, sizeof(req)); return (retval == sizeof(req)) ? 0:-1; }
int raw1394_start_phy_packet_write(struct raw1394_handle *handle, quadlet_t data, unsigned long tag) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_PHYPACKET; req.generation = handle->generation; req.tag = tag; req.sendb = data; return (int)write(handle->fd, &req, sizeof(req)); }
int raw1394_echo_request(struct raw1394_handle *handle, quadlet_t data) { struct raw1394_request req; int retval=0; CLEAR_REQ(&req); req.type = RAW1394_REQ_ECHO; req.misc = data; retval = (int)write(handle->fd, &req, sizeof(req)); if (retval == sizeof(req)) { return 0; /* succcess */ } return -1; }
/* * AdressRangeMapping GET BUFFER: * start, length .... identifies addressrange * buf .............. pointer to buffer * * This function copies 'length' bytes from one * ARM block in kernel memory area with start offset `start` * to user memory area 'buf' * * returnvalue: 0 ... success * <0 ... failure, and errno - error code */ int ieee1394_arm_get_buf (struct ieee1394_handle *handle, nodeaddr_t start, size_t length, void *buf) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_ARM_GET_BUF; req.recvb = ptr2int(buf); req.length = length; req.address = start; if (write(handle->fd, &req, sizeof(req)) < 0) return -1; return 0; }
int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr, size_t length, quadlet_t *data, unsigned long tag) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_ASYNC_WRITE; req.generation = handle->generation; req.tag = tag; req.address = ((__u64)node << 48) | addr; req.length = length; req.sendb = ptr2int(data); return (int)write(handle->fd, &req, sizeof(req)); }
int raw1394_start_async_send(struct raw1394_handle *handle, size_t length, size_t header_length, unsigned int expect_response, quadlet_t *data, unsigned long rawtag) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_ASYNC_SEND; req.generation = handle->generation; req.tag = rawtag; req.length = length; req.misc = (expect_response << 16) | (header_length & 0xffff); req.sendb = ptr2int(data); return (int)write(handle->fd, &req, sizeof(req)); }
int raw1394_start_iso_write(struct raw1394_handle *handle, unsigned int channel, unsigned int tag, unsigned int sy, unsigned int speed, size_t length, quadlet_t *data, unsigned long rawtag) { struct raw1394_request req; CLEAR_REQ(&req); req.type = RAW1394_REQ_ISO_SEND; req.generation = handle->generation; req.tag = rawtag; req.address = ((__u64)channel << 48) | speed; req.misc = (tag << 16) | sy; req.length = length; req.sendb = ptr2int(data); return (int)write(handle->fd, &req, sizeof(req)); }
int raw1394_start_lock64(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr, unsigned int extcode, octlet_t data, octlet_t arg, octlet_t *result, unsigned long tag) { struct raw1394_request req; octlet_t sendbuf[2]; if ((extcode > 7) || (extcode == 0)) { errno = EINVAL; return -1; } CLEAR_REQ(&req); req.type = RAW1394_REQ_LOCK64; req.generation = handle->generation; req.tag = tag; req.address = ((__u64)node << 48) | addr; req.sendb = ptr2int(sendbuf); req.recvb = ptr2int(result); req.misc = extcode; switch (extcode) { case 3: /* EXTCODE_FETCH_ADD */ case 4: /* EXTCODE_LITTLE_ADD */ sendbuf[0] = data; req.length = 8; break; default: sendbuf[0] = arg; sendbuf[1] = data; req.length = 16; break; } return (int)write(handle->fd, &req, sizeof(req)); }