Changeset 70c12d6 in mainline
- Timestamp:
- 2011-05-11T19:20:06Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cf002dbf
- Parents:
- 19387b61
- Location:
- uspace/drv/usbmast
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbmast/Makefile
r19387b61 r70c12d6 41 41 42 42 SOURCES = \ 43 inquiry.c \ 43 44 main.c \ 44 45 mast.c -
uspace/drv/usbmast/main.c
r19387b61 r70c12d6 75 75 }; 76 76 77 #define BITS_GET_MASK(type, bitcount) (((type)(1 << (bitcount)))-1)78 #define BITS_GET_MID_MASK(type, bitcount, offset) \79 ((type)( BITS_GET_MASK(type, (bitcount) + (offset)) - BITS_GET_MASK(type, bitcount) ))80 #define BITS_GET(type, number, bitcount, offset) \81 ((type)( (number) & (BITS_GET_MID_MASK(type, bitcount, offset)) ) >> (offset))82 83 #define INQUIRY_RESPONSE_LENGTH 3584 85 static void try_inquiry(usb_device_t *dev)86 {87 scsi_cmd_inquiry_t inquiry = {88 .op_code = 0x12,89 .lun_evpd = 0,90 .page_code = 0,91 .alloc_length = INQUIRY_RESPONSE_LENGTH,92 .ctrl = 093 };94 size_t response_len;95 uint8_t response[INQUIRY_RESPONSE_LENGTH];96 97 int rc;98 99 rc = usb_massstor_data_in(GET_BULK_IN(dev), GET_BULK_OUT(dev),100 0xDEADBEEF, 0, (uint8_t *) &inquiry, sizeof(inquiry),101 response, INQUIRY_RESPONSE_LENGTH, &response_len);102 103 if (rc != EOK) {104 usb_log_error("Failed to probe device %s using %s: %s.\n",105 dev->ddf_dev->name, "SCSI:INQUIRY", str_error(rc));106 return;107 }108 109 if (response_len < 8) {110 usb_log_error("The SCSI response is too short.\n");111 return;112 }113 114 /*115 * This is an ugly part of the code. We will parse the returned116 * data by hand and try to get as many useful data as possible.117 */118 int device_type = BITS_GET(uint8_t, response[0], 5, 0);119 int removable = BITS_GET(uint8_t, response[1], 1, 7);120 121 usb_log_info("SCSI information for device `%s':\n", dev->ddf_dev->name);122 usb_log_info(" - peripheral device type: %d\n", device_type);123 usb_log_info(" - removable: %s\n", removable ? "yes" : "no");124 125 if (response_len < 32) {126 return;127 }128 129 char dev_vendor[9];130 str_ncpy(dev_vendor, 9, (const char *) &response[8], 8);131 usb_log_info(" - vendor: '%s'\n", dev_vendor);132 133 char dev_product[9];134 str_ncpy(dev_product, 9, (const char *) &response[16], 8);135 usb_log_info(" - product: '%s'\n", dev_vendor);136 }137 138 77 /** Callback when new device is attached and recognized as a mass storage. 139 78 * … … 168 107 (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size); 169 108 170 try_inquiry(dev); 109 int lun_count = usb_massstor_get_max_lun(dev); 110 /* Return value: 111 * rc < 0 => device does not know this request, only single LUN 112 * could be present 113 * rc >= 0 - the rc is the maximum LUN, thus count is +1 114 */ 115 if (lun_count < 0) { 116 lun_count = 1; 117 } else { 118 lun_count++; 119 } 120 121 usb_massstor_inquiry_result_t inquiry; 122 rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry); 123 if (rc != EOK) { 124 usb_log_warning("Failed to inquiry device `%s': %s.\n", 125 dev->ddf_dev->name, str_error(rc)); 126 return EOK; 127 } 128 129 usb_log_info("Mass storage `%s': `%s' by `%s' is %s (%s), %d LUN(s).\n", 130 dev->ddf_dev->name, 131 inquiry.product_and_revision, inquiry.vendor_id, 132 usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type), 133 inquiry.removable ? "removable" : "non-removable", 134 lun_count); 171 135 172 136 return EOK; -
uspace/drv/usbmast/mast.c
r19387b61 r70c12d6 40 40 #include <str_error.h> 41 41 #include <usb/debug.h> 42 #include <usb/request.h> 42 43 43 44 bool usb_mast_verbose = true; … … 63 64 * @return Error code. 64 65 */ 65 int usb_massstor_data_in(usb_pipe_t *bulk_in_pipe, usb_pipe_t *bulk_out_pipe, 66 int usb_massstor_data_in(usb_device_t *dev, 67 size_t bulk_in_pipe_index, size_t bulk_out_pipe_index, 66 68 uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size, 67 69 void *in_buffer, size_t in_buffer_size, size_t *received_size) … … 69 71 int rc; 70 72 size_t act_size; 73 usb_pipe_t *bulk_in_pipe = dev->pipes[bulk_in_pipe_index].pipe; 74 usb_pipe_t *bulk_out_pipe = dev->pipes[bulk_out_pipe_index].pipe; 71 75 72 76 /* Prepare CBW - command block wrapper */ … … 135 139 } 136 140 141 int usb_massstor_reset(usb_device_t *dev) 142 { 143 return usb_control_request_set(&dev->ctrl_pipe, 144 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 145 0xFF, 0, dev->interface_no, NULL, 0); 146 } 147 148 void usb_massstor_reset_recovery(usb_device_t *dev, 149 size_t bulk_in_idx, size_t bulk_out_idx) 150 { 151 /* We would ignore errors here because if this fails 152 * we are doomed anyway and any following transaction would fail. 153 */ 154 usb_massstor_reset(dev); 155 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe); 156 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe); 157 } 158 159 int usb_massstor_get_max_lun(usb_device_t *dev) 160 { 161 uint8_t max_lun; 162 size_t data_recv_len; 163 int rc = usb_control_request_get(&dev->ctrl_pipe, 164 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 165 0xFE, 0, dev->interface_no, &max_lun, 1, &data_recv_len); 166 if (rc != EOK) { 167 return rc; 168 } 169 if (data_recv_len != 1) { 170 return EEMPTY; 171 } 172 return (int) max_lun; 173 } 174 137 175 /** 138 176 * @} -
uspace/drv/usbmast/mast.h
r19387b61 r70c12d6 40 40 #include <usb/usb.h> 41 41 #include <usb/pipes.h> 42 #include <usb/devdrv.h> 42 43 43 int usb_massstor_data_in(usb_pipe_t *, usb_pipe_t *, uint32_t, uint8_t, 44 void *, size_t, void *, size_t, size_t *); 44 typedef struct { 45 int peripheral_device_type; 46 bool removable; 47 char vendor_id[9]; 48 char product_and_revision[12]; 49 } usb_massstor_inquiry_result_t; 50 51 int usb_massstor_data_in(usb_device_t *dev, size_t, size_t, 52 uint32_t, uint8_t, void *, size_t, void *, size_t, size_t *); 53 int usb_massstor_reset(usb_device_t *); 54 void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t); 55 int usb_massstor_get_max_lun(usb_device_t *); 56 int usb_massstor_inquiry(usb_device_t *, size_t, size_t, 57 usb_massstor_inquiry_result_t *); 58 const char *usb_str_masstor_scsi_peripheral_device_type(int); 45 59 46 60 #endif
Note:
See TracChangeset
for help on using the changeset viewer.