/* * submits a control message and waits for comletion (at least timeout * 1ms) * If timeout is 0, we don't wait for completion (used as example to set and * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). * returns the transfered length if OK or -1 if error. The transfered length * and the current status are stored in the dev->act_len and dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, void *data, unsigned short size, int timeout) { if((timeout==0)&&(!asynch_allowed)) /* request for a asynch control pipe is not allowed */ return -1; /* set setup command */ setup_packet.requesttype = requesttype; setup_packet.request = request; setup_packet.value = swap_16(value); setup_packet.index = swap_16(index); setup_packet.length = swap_16(size); USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X\nvalue 0x%X index 0x%X length 0x%X\n", request,requesttype,value,index,size); dev->status=USB_ST_NOT_PROC; /*not yet processed */ submit_control_msg(dev,pipe,data,size,&setup_packet); if(timeout==0) { return (int)size; } while(timeout--) { if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) break; wait_ms(1); } if(dev->status==0) return dev->act_len; else { return -1; } }
/* * submits a control message and waits for comletion (at least timeout * 1ms) * If timeout is 0, we don't wait for completion (used as example to set and * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). * returns the transfered length if OK or -1 if error. The transfered length * and the current status are stored in the dev->act_len and dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, void *data, unsigned short size, int timeout) { ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1); int err; if ((timeout == 0) && (!asynch_allowed)) { /* request for a asynch control pipe is not allowed */ return -EINVAL; } /* set setup command */ setup_packet->requesttype = requesttype; setup_packet->request = request; setup_packet->value = cpu_to_le16(value); setup_packet->index = cpu_to_le16(index); setup_packet->length = cpu_to_le16(size); //debug("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ // "value 0x%X index 0x%X length 0x%X timeout %d.\r\n", // request, requesttype, value, index, size,timeout); dev->status = USB_ST_NOT_PROC; /*not yet processed */ err = submit_control_msg(dev, pipe, data, size, setup_packet); if (err < 0) { //debug("Submit control msg failed with err = %d.\r\n", err); return err; } if (timeout == 0) return (int)size; /* * Wait for status to update until timeout expires, USB driver * interrupt handler may set the status when the USB operation has * been completed. */ while (timeout--) { if (!(dev->status & USB_ST_NOT_PROC)) break; mdelay(1); } if (dev->status) { debug("Submit control msg return -1.\r\n"); return -1; } //debug("Submit control msg return with value %d.\r\n", dev->act_len); return dev->act_len; }
/*--- Dispatcher ---*/ int32 USBHost::dispatch(uint32 fncode) { int32 ret; D(bug("USBHost: dispatch(%u)", fncode)); ret = EINVFN; switch(fncode) { case GET_VERSION: D(bug("USBHost: getVersion")); ret = USBHOST_NFAPI_VERSION; break; case USBHOST_INTLEVEL: D(bug("USBHost: getINTlevel")); ret = INTLEVEL; break; case USBHOST_RH_PORT_STATUS: ret = rh_port_status(getParameter(0)); break; case USBHOST_LOWLEVEL_INIT: ret = usb_lowlevel_init(); break; case USBHOST_LOWLEVEL_STOP: ret = usb_lowlevel_stop(); break; case USBHOST_SUBMIT_CONTROL_MSG: ret = submit_control_msg(getParameter(0), getParameter(1), getParameter(2), getParameter(3)); break; case USBHOST_SUBMIT_INT_MSG: ret = submit_int_msg(getParameter(0), getParameter(1), getParameter(2), getParameter(3)); break; case USBHOST_SUBMIT_BULK_MSG: ret = submit_bulk_msg(getParameter(0), getParameter(1), getParameter(2)); break; default: D(bug("USBHost: unimplemented function #%d", fncode)); break; } D(bug("USBHost: function returning with 0x%08x", ret)); return ret; }
/* * submits a control message and waits for comletion (at least timeout * 1ms) * If timeout is 0, we don't wait for completion (used as example to set and * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). * returns the transfered length if OK or -1 if error. The transfered length * and the current status are stored in the dev->act_len and dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, void *data, unsigned short size, int timeout) { ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1); if ((timeout == 0) && (!asynch_allowed)) { /* request for a asynch control pipe is not allowed */ debug("%s: timed out\n", __func__); return -1; } /* set setup command */ setup_packet->requesttype = requesttype; setup_packet->request = request; setup_packet->value = cpu_to_le16(value); setup_packet->index = cpu_to_le16(index); setup_packet->length = cpu_to_le16(size); debug("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ "value 0x%X index 0x%X length 0x%X\n", request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0) { debug("%s: submit_control_msg error\n", __func__); return -1; } if (timeout == 0) { debug("%s: msg size: %d\n", __func__, size); return (int)size; } /* * Wait for status to update until timeout expires, USB driver * interrupt handler may set the status when the USB operation has * been completed. */ while (timeout--) { if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) break; mdelay(1); } if (dev->status) return -1; debug("%s: act len: %d\n", __func__, dev->act_len); return dev->act_len; }
/* * submits a control message and waits for comletion (at least timeout * 1ms) * If timeout is 0, we don't wait for completion (used as example to set and * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). * returns the transfered length if OK or -1 if error. The transfered length * and the current status are stored in the dev->act_len and dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, void *data, unsigned short size, int timeout) { if ((timeout == 0) && (!asynch_allowed)) { /* request for a asynch control pipe is not allowed */ return -1; } /* set setup command */ setup_packet.requesttype = requesttype; setup_packet.request = request; setup_packet.value = cpu_to_le16(value); setup_packet.index = cpu_to_le16(index); setup_packet.length = cpu_to_le16(size); USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ "value 0x%X index 0x%X length 0x%X\n", request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ submit_control_msg(dev, pipe, data, size, &setup_packet); if (USB_ST_DISCONNECT==dev->status) return -3; //USB_STOR_TRANSPORT_NODEV if(timeout==0) { return (int)size; } /* * Wait for status to update until timeout expires, USB driver * interrupt handler may set the status when the USB operation has * been completed. */ while(timeout>0) { if(!(dev->status & USB_ST_NOT_PROC)) break; wait_ms(1); timeout--; } if(dev->status==0) return dev->act_len; else { return -1; } }
/* * submits a control message and waits for comletion (at least timeout * 1ms) * If timeout is 0, we don't wait for completion (used as example to set and * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). * returns the transfered length if OK or -1 if error. The transfered length * and the current status are stored in the dev->act_len and dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, void *data, unsigned short size, int timeout) { ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1); if ((timeout == 0) && (!asynch_allowed)) { /* request for a asynch control pipe is not allowed */ return -1; } /* set setup command */ setup_packet->requesttype = requesttype; setup_packet->request = request; setup_packet->value = cpu_to_le16(value); setup_packet->index = cpu_to_le16(index); setup_packet->length = cpu_to_le16(size); USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ "value 0x%X index 0x%X length 0x%X\n", request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ submit_control_msg(dev, pipe, data, size, setup_packet); if (timeout == 0) return (int)size; if (dev->status != 0) { /* * Let's wait a while for the timeout to elapse. * It has no real use, but it keeps the interface happy. */ wait_ms(timeout); return -1; } return dev->act_len; }