73extern UMAS_DATA_T *g_umas;
75#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
76 vendorName, productName,useProtocol, useTransport, \
77 initFunction, flags) \
78USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax)
80static USB_DEV_ID_T _UmasDeviceIDs[] =
85 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_RBC, UMAS_PR_CB),
86 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_8020, UMAS_PR_CB),
87 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_QIC, UMAS_PR_CB),
88 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_UFI, UMAS_PR_CB),
89 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_8070, UMAS_PR_CB),
90 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_SCSI, UMAS_PR_CB),
93 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_RBC, UMAS_PR_CBI),
94 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_8020, UMAS_PR_CBI),
95 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_QIC, UMAS_PR_CBI),
96 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_UFI, UMAS_PR_CBI),
97 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_8070, UMAS_PR_CBI),
98 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_SCSI, UMAS_PR_CBI),
101 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_RBC, UMAS_PR_BULK),
102 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_8020, UMAS_PR_BULK),
103 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_QIC, UMAS_PR_BULK),
104 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_UFI, UMAS_PR_BULK),
105 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_8070, UMAS_PR_BULK),
106 USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, UMAS_SC_SCSI, UMAS_PR_BULK),
109 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
114#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
115 vendor_name, product_name, use_protocol, use_transport, \
116 init_function, Flags) \
117{ vendor_name, product_name, use_protocol, use_transport, init_function, Flags }
119static UMAS_UUDEV_T _UmasUUDevList[] =
123 { UMAS_SC_RBC, UMAS_PR_CB },
124 { UMAS_SC_8020, UMAS_PR_CB },
125 { UMAS_SC_QIC, UMAS_PR_CB },
126 { UMAS_SC_UFI, UMAS_PR_CB },
127 { UMAS_SC_8070, UMAS_PR_CB },
128 { UMAS_SC_SCSI, UMAS_PR_CB },
131 { UMAS_SC_RBC, UMAS_PR_CBI },
132 { UMAS_SC_8020, UMAS_PR_CBI },
133 { UMAS_SC_QIC, UMAS_PR_CBI },
134 { UMAS_SC_UFI, UMAS_PR_CBI },
135 { UMAS_SC_8070, UMAS_PR_CBI },
136 { UMAS_SC_SCSI, UMAS_PR_CBI },
139 { UMAS_SC_RBC, UMAS_PR_BULK },
140 { UMAS_SC_8020, UMAS_PR_BULK },
141 { UMAS_SC_QIC, UMAS_PR_BULK },
142 { UMAS_SC_UFI, UMAS_PR_BULK },
143 { UMAS_SC_8070, UMAS_PR_BULK },
144 { UMAS_SC_SCSI, UMAS_PR_BULK },
151static UMAS_DATA_T _umas_pool[UMAS_MAX_DEV];
152static uint8_t _umac_alloc_mark[UMAS_MAX_DEV];
155extern void free_umas_drive(UMAS_DRIVE_T * umas_drive);
158static UMAS_DATA_T * alloc_umas()
161 for (i = 0; i < UMAS_MAX_DEV; i++)
163 if (_umac_alloc_mark[i] == 0)
165 _umac_alloc_mark[i] = 1;
166 return &_umas_pool[i];
173void free_umas(UMAS_DATA_T * umas)
178 for (i = 0; i < UMAS_MAX_DEV; i++)
180 if (umas == &_umas_pool[i])
181 _umac_alloc_mark[i] = 0;
187static void storage_disconnect(
USB_DEV_T *dev);
189USB_DRIVER_T _UsbMassStorageDriver =
208static int usb_stor_allocate_irq(UMAS_DATA_T *umas)
213 uint8_t bEndpointAddress, bInterval;
215 UMAS_DEBUG(
"Allocating IRQ for CBI transport\n");
217 bEndpointAddress = umas->pusb_dev->ep_list[umas->ep_int].bEndpointAddress;
218 bInterval = umas->pusb_dev->ep_list[umas->ep_int].bInterval;
224 UMAS_DEBUG(
"couldn't allocate interrupt URB");
229 pipe = usb_rcvintpipe(umas->pusb_dev, (bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
230 maxp = usb_maxpacket(umas->pusb_dev, pipe, usb_pipeout(pipe));
231 if (maxp >
sizeof(umas->irqbuf))
232 maxp =
sizeof(umas->irqbuf);
235 FILL_INT_URB(umas->irq_urb, umas->pusb_dev, pipe, umas->irqbuf, maxp,
236 UMAS_CbiIrq, umas, bInterval);
253 const int id_index =
id - _UmasDeviceIDs;
254 UMAS_UUDEV_T *unusual_dev;
255 UMAS_DATA_T *umas =
NULL;
259 uint8_t subclass = 0;
260 uint8_t protocol = 0;
262 ifnum = ifd->bInterfaceNumber;
266 if (id_index <
sizeof(_UmasUUDevList) /
sizeof(_UmasUUDevList[0]))
268 unusual_dev = &_UmasUUDevList[id_index];
275 UMAS_DEBUG(
"USB Mass Storage device detected\n");
278 subclass = unusual_dev->useProtocol;
279 protocol = unusual_dev->useTransport;
287 for (i = 1; i < dev->ep_list_cnt; i++)
289 if (dev->ep_list[i].ifnum != ifnum)
293 if ((dev->ep_list[i].bmAttributes &
294 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
297 if (dev->ep_list[i].bEndpointAddress & USB_DIR_IN)
304 if ((dev->ep_list[i].bmAttributes &
305 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
314 if (!ep_in || !ep_out || ((protocol == UMAS_PR_CBI) && !ep_int))
316 UMAS_DEBUG(
"Endpoint sanity check failed! Rejecting dev.\n");
323 UMAS_DEBUG(
"umas - Out of memory\n");
326 memset((
char *)umas, 0,
sizeof(UMAS_DATA_T));
330 if (!umas->current_urb)
337 umas->subclass = subclass;
338 umas->protocol = protocol;
340 umas->unusual_dev = unusual_dev;
344 umas->ep_in = dev->ep_list[ep_in].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
346 umas->ep_out = dev->ep_list[ep_out].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
347 umas->ep_int = ep_int;
351 umas->pusb_dev = dev;
352 umas->vendor_id = dev->descriptor.idVendor;
353 umas->product_id = dev->descriptor.idProduct;
354 umas->sector_size = 0;
355 umas->sector_number = 0;
361 switch (umas->protocol)
364 umas->transport_name =
"Control/Bulk";
365 umas->transport = UMAS_CbTransport;
366 umas->transport_reset = UMAS_CbReset;
371 umas->transport_name =
"Control/Bulk/Interrupt";
372 umas->transport = UMAS_CbiTransport;
373 umas->transport_reset = UMAS_CbReset;
378 umas->transport_name =
"Bulk-only";
379 umas->transport = UMAS_BulkTransport;
380 umas->transport_reset = UMAS_BulkReset;
381 umas->max_lun = UMAS_BulkMaxLun(umas);
382 UMAS_DEBUG(
"Bulk max logical unit number: %d\n", umas->max_lun);
386 umas->transport_name =
"Unknown";
390 UMAS_DEBUG(
"Mass storage transport: %s\n", umas->transport_name);
393 if (umas->flags & UMAS_FL_SINGLE_LUN)
396 switch (umas->subclass)
399 umas->protocol_name =
"Reduced Block Commands (RBC)";
400 umas->proto_handler = UMAS_TransparentScsiCommand;
404 umas->protocol_name =
"8020i";
405 umas->proto_handler = UMAS_AtapiCommand;
410 umas->protocol_name =
"QIC-157";
411 umas->proto_handler = UMAS_Qic157Command;
416 umas->protocol_name =
"8070i";
417 umas->proto_handler = UMAS_AtapiCommand;
422 umas->protocol_name =
"Transparent SCSI";
423 umas->proto_handler = UMAS_TransparentScsiCommand;
427 umas->protocol_name =
"Uniform Floppy Interface (UFI)";
428 umas->proto_handler = UMAS_UfiCommand;
432 umas->protocol_name =
"Unknown";
436 UMAS_DEBUG(
"Mass storage protocol: %s\n", umas->protocol_name);
439 if ((umas->protocol == UMAS_PR_CBI) && usb_stor_allocate_irq(umas))
444 UMAS_DEBUG(
"WARNING: USB Mass Storage data integrity not assured\n");
445 UMAS_DEBUG(
"USB Mass Storage device found at %d\n", dev->devnum);
447 if (UMAS_InitUmasDevice(umas) < 0)
453 if (umas->current_urb)
465static void storage_disconnect(
USB_DEV_T *dev)
467 UMAS_DATA_T *umas =
NULL;
469 UMAS_DRIVE_T *umas_drive, *next_drv;
473 UMAS_DEBUG(
"storage_disconnect called\n");
475 for (i = 0; i < UMAS_MAX_DEV; i++)
477 if ((_umac_alloc_mark[i]) && (_umas_pool[i].pusb_dev == dev))
478 umas = &_umas_pool[i];
484 UMAS_DEBUG(
"storage_disconnect - device not in use\n");
490 umas_drive = umas->drive_list;
491 while (umas_drive !=
NULL)
493 next_drv = umas_drive->next;
494 fsPhysicalDiskDisconnected(umas_drive->client);
495 free_umas_drive(umas_drive);
496 umas_drive = next_drv;
502 UMAS_DEBUG(
"storage_disconnect -- releasing irq URB\n");
504 UMAS_DEBUG(
"storage_disconnect -- usb_unlink_urb() returned %d\n",
USBH_UnlinkUrb(umas->irq_urb));
509 umas->irq_urb =
NULL;
513 UMAS_DEBUG(
"storage_disconnect -- releasing main URB\n");
515 UMAS_DEBUG(
"storage_disconnect -- usb_unlink_urb() returned %d\n",
USBH_UnlinkUrb(umas->current_urb));
520 umas->current_urb =
NULL;
527void UMAS_ScanAllDevice()
530 for (i = 0; i < UMAS_MAX_DEV; i++)
532 if (_umac_alloc_mark[i] == 0)
535 UMAS_ScanDeviceLun(&_umas_pool[i]);
570 for (i = 0; i < UMAS_MAX_DEV; i++)
571 _umac_alloc_mark[i] = 0;
591 for (i = 0, idx = 0; (i < UMAS_MAX_DEV) && (idx < max); i++)
593 if (_umac_alloc_mark[i])
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
int32_t USBH_RegisterDriver(USB_DRIVER_T *new_driver)
Register a device driver to USB Host Core driver.
int32_t USBH_SubmitUrb(URB_T *urb)
Submit an URB to USB core for transfer data.
int32_t USBH_UnlinkUrb(URB_T *urb)
Cancel an URB which has been submit to USB core.
URB_T * USBH_AllocUrb(void)
Allocate an URB from USB Core driver internal URB pool.
void USBH_FreeUrb(URB_T *)
Free the URB allocated from USBH_AllocUrb()
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
int32_t USBH_MassGetDiskList(mass_disk_t *dlist[], int max)
Obtain the list of currently connected USB Mass Storage disk.
int32_t USBH_MassInit(void)
Initialize USB Host Mass Storage driver.
#define NULL
NULL pointer.
USB Host core driver header file.
USB Host Mass Storage driver header file.