void usb_bulk_reset(mass_dev* dev, int mode) { int ret; usb_callback_data cb_data; iop_sema_t s; s.initial = 0; s.max = 1; s.option = 0; s.attr = 0; cb_data.semh = CreateSema(&s); //Call Bulk only mass storage reset ret = UsbControlTransfer( dev->controlEp, //default pipe 0x21, //bulk reset 0xFF, 0, dev->interfaceNumber, //interface number 0, //length NULL, //data usb_callback, (void*) &cb_data ); if (ret != USB_RC_OK) { printf("USBHDFSD: Error - sending reset %d\n", ret); } else { WaitSema(cb_data.semh); //clear bulk-in endpoint if (mode & 0x01) { usb_bulk_clear_halt(dev, 0); } //clear bulk-out endpoint if (mode & 0x02) { usb_bulk_clear_halt(dev, 1); } } DeleteSema(cb_data.semh); }
static void usb_bulk_reset(mass_dev* dev, int mode) { int ret; usb_callback_data cb_data; cb_data.semh = dev->ioSema; //Call Bulk only mass storage reset ret = UsbControlTransfer( dev->controlEp, //default pipe 0x21, //bulk reset 0xFF, 0, dev->interfaceNumber, //interface number 0, //length NULL, //data usb_callback, (void*) &cb_data ); if (ret == USB_RC_OK) { WaitSema(cb_data.semh); ret = cb_data.returnCode; } if(ret == USB_RC_OK) { //clear bulk-in endpoint if (mode & 0x01) ret = usb_bulk_clear_halt(dev, USB_BLK_EP_IN); } if(ret == USB_RC_OK) { //clear bulk-out endpoint if (mode & 0x02) ret = usb_bulk_clear_halt(dev, USB_BLK_EP_OUT); } if(ret != USB_RC_OK){ XPRINTF("USBHDFSD: Error - sending reset %d to device %d.\n", ret, dev->devId); dev->status |= USBMASS_DEV_STAT_ERR; } }
static int usb_bulk_get_max_lun(mass_dev* dev) { int ret; usb_callback_data cb_data; char max_lun; cb_data.semh = dev->ioSema; //Call Bulk only mass storage reset ret = UsbControlTransfer( dev->controlEp, //default pipe 0xA1, 0xFE, 0, dev->interfaceNumber, //interface number 1, //length &max_lun, //data usb_callback, (void*) &cb_data ); if (ret == USB_RC_OK) { WaitSema(cb_data.semh); ret = cb_data.returnCode; } if(ret == USB_RC_OK){ ret = max_lun; } else { //Devices that do not support multiple LUNs may STALL this command. usb_bulk_clear_halt(dev, USB_BLK_EP_IN); usb_bulk_clear_halt(dev, USB_BLK_EP_OUT); ret = -ret; } return ret; }
static int usb_bulk_transfer(mass_dev* dev, int direction, void* buffer, unsigned int transferSize) { int ret; unsigned char* buf = (unsigned char*) buffer; int blockSize = transferSize; int offset = 0, pipe; usb_callback_data cb_data; cb_data.semh = dev->ioSema; pipe = (direction==USB_BLK_EP_IN) ? dev->bulkEpI : dev->bulkEpO; while (transferSize > 0) { if (transferSize < blockSize) { blockSize = transferSize; } ret = UsbBulkTransfer( pipe, //bulk pipe epI(Read) epO(Write) (buf + offset), //data ptr blockSize, //data length usb_callback, (void*)&cb_data ); if (ret != USB_RC_OK) { cb_data.returnCode = ret; break; } else { WaitSema(cb_data.semh); //XPRINTF("USBHDFSD: retCode=%i retSize=%i \n", cb_data.returnCode, cb_data.returnSize); if (cb_data.returnCode != USB_RC_OK) { break; } offset += cb_data.returnSize; transferSize-= cb_data.returnSize; } } if(cb_data.returnCode != USB_RC_OK){ XPRINTF("USBHDFSD: Error - bulk data transfer %d. Clearing HALT state.\n", cb_data.returnCode); usb_bulk_clear_halt(dev, direction); } return cb_data.returnCode; }
/* see flow chart in the usbmassbulk_10.pdf doc (page 15) Returned values: <0 Low-level USBD error. 0 = Command completed successfully. 1 = Command failed. 2 = Phase error. */ static int usb_bulk_manage_status(mass_dev* dev, unsigned int tag) { int ret; csw_packet csw; //XPRINTF("USBHDFSD: usb_bulk_manage_status 1 ...\n"); ret = usb_bulk_status(dev, &csw, tag); /* Attempt to read CSW from bulk in endpoint */ if (ret != USB_RC_OK) { /* STALL bulk in -OR- Bulk error */ usb_bulk_clear_halt(dev, USB_BLK_EP_IN); /* clear the stall condition for bulk in */ XPRINTF("USBHDFSD: usb_bulk_manage_status error %d ...\n", ret); ret = usb_bulk_status(dev, &csw, tag); /* Attempt to read CSW from bulk in endpoint */ } /* CSW not valid or stalled or phase error */ if (ret != USB_RC_OK || csw.signature != CSW_TAG || csw.tag != tag || csw.status == 2) { printf("USBHDFSD: usb_bulk_manage_status call reset recovery ...\n"); usb_bulk_reset(dev, 3); /* Perform reset recovery */ } return((ret == USB_RC_OK && csw.signature == CSW_TAG && csw.tag == tag) ? csw.status : -1); }
/* see flow chart in the usbmassbulk_10.pdf doc (page 15) */ int usb_bulk_manage_status(mass_dev* dev, int tag) { int ret; csw_packet csw; //XPRINTF("USBHDFSD: usb_bulk_manage_status 1 ...\n"); ret = usb_bulk_status(dev, &csw, tag); /* Attempt to read CSW from bulk in endpoint */ if (ret < 0) { /* STALL bulk in -OR- Bulk error */ usb_bulk_clear_halt(dev, 0); /* clear the stall condition for bulk in */ XPRINTF("USBHDFSD: usb_bulk_manage_status stall ...\n"); ret = usb_bulk_status(dev, &csw, tag); /* Attempt to read CSW from bulk in endpoint */ } /* CSW not valid or stalled or phase error */ if (csw.signature != CSW_TAG || csw.tag != tag || ret == 2) { printf("USBHDFSD: usb_bulk_manage_status call reset recovery ...\n"); usb_bulk_reset(dev, 3); /* Perform reset recovery */ } return ret; }