Changeset 55054db0 in mainline
- Timestamp:
- 2011-05-13T13:44:19Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 852803a
- Parents:
- 3e4f2e0 (diff), c372e03 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ehci-hcd/pci.c
r3e4f2e0 r55054db0 54 54 55 55 #define CMD_OFFSET 0x0 56 #define CONFIGFLAG_OFFSET 0x40 56 #define STS_OFFSET 0x4 57 #define CFG_OFFSET 0x40 57 58 58 59 #define USBCMD_RUN 1 … … 264 265 * It would prevent pre-OS code from interfering. */ 265 266 ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 266 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0); 267 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 268 0xe0000000); 267 269 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 268 usb_log_debug("Zeroed USBLEGCTLSTS register.\n");269 270 270 271 /* Read again Legacy Support and Control register */ … … 291 292 volatile uint32_t *usbcmd = 292 293 (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET); 294 volatile uint32_t *usbsts = 295 (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET); 293 296 volatile uint32_t *usbconfigured = 294 (uint32_t*)((uint8_t*)registers + operation_offset 295 + CONFIGFLAG_OFFSET); 297 (uint32_t*)((uint8_t*)registers + operation_offset + CFG_OFFSET); 296 298 usb_log_debug("USBCMD value: %x.\n", *usbcmd); 297 299 if (*usbcmd & USBCMD_RUN) { 298 300 *usbcmd = 0; 301 while (!(*usbsts & (1 << 12))); /*wait until hc is halted */ 299 302 *usbconfigured = 0; 300 303 usb_log_info("EHCI turned off.\n"); … … 302 305 usb_log_info("EHCI was not running.\n"); 303 306 } 307 usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n", 308 *usbcmd, *usbsts, *usbconfigured); 304 309 305 310 async_hangup(parent_phone); -
uspace/drv/uhci-rhd/port.c
r3e4f2e0 r55054db0 32 32 * @brief UHCI root hub port routines 33 33 */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 35 #include <fibril_synch.h> /* async_usleep */ 35 36 #include <errno.h> 36 37 #include <str_error.h> 37 #include <fibril_synch.h>38 38 39 39 #include <usb/usb.h> /* usb_address_t */ 40 #include <usb/hub.h> 40 #include <usb/hub.h> /* usb_hc_new_device_wrapper */ 41 41 #include <usb/debug.h> 42 42 … … 212 212 213 213 /* 214 * The host then waits for at least 100 ms to allow completion of 215 * an insertion process and for power at the device to become stable. 216 */ 217 async_usleep(100000); 218 219 /* 220 * Resets from root ports should be nominally 50ms 214 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3) 221 215 */ 222 216 { … … 229 223 port_status &= ~STATUS_IN_RESET; 230 224 uhci_port_write_status(port, port_status); 231 usb_log_debug("%s: Reset Signal stop.\n", port->id_string);232 }233 234 /* the reset recovery time 10ms */235 async_usleep(10000);236 225 while (uhci_port_read_status(port) & STATUS_IN_RESET); 226 // TODO: find a better way to waste time (it should be less than 227 // 10ms, if we reschedule it takes too much time (random 228 // interrupts can be solved by multiple attempts). 229 usb_log_debug2("%s: Reset Signal stop.\n", port->id_string); 230 } 237 231 /* Enable the port. */ 238 232 uhci_port_set_enabled(port, true); 233 234 /* Reset recovery period, 235 * devices do not have to respond during this period 236 */ 237 async_usleep(10000); 239 238 return EOK; 240 239 } … … 255 254 usb_log_debug("%s: Detected new device.\n", port->id_string); 256 255 256 int ret, count = 0; 257 257 usb_address_t dev_addr; 258 int ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 259 speed, uhci_port_reset_enable, port->number, port, 260 &dev_addr, &port->attached_device, NULL, NULL, NULL); 258 do { 259 ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 260 speed, uhci_port_reset_enable, port->number, port, 261 &dev_addr, &port->attached_device, NULL, NULL, NULL); 262 } while (ret != EOK && ++count < 4); 261 263 262 264 if (ret != EOK) { … … 313 315 /* Wait for port to become enabled */ 314 316 do { 315 async_usleep(1000);316 317 port_status = uhci_port_read_status(port); 317 318 } while ((port_status & STATUS_CONNECTED) && -
uspace/drv/usbmast/Makefile
r3e4f2e0 r55054db0 41 41 42 42 SOURCES = \ 43 inquiry.c \ 43 44 main.c \ 44 45 mast.c -
uspace/drv/usbmast/main.c
r3e4f2e0 r55054db0 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 size_t lun_count = usb_masstor_get_lun_count(dev); 110 111 usb_massstor_inquiry_result_t inquiry; 112 rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry); 113 if (rc != EOK) { 114 usb_log_warning("Failed to inquiry device `%s': %s.\n", 115 dev->ddf_dev->name, str_error(rc)); 116 return EOK; 117 } 118 119 usb_log_info("Mass storage `%s': " \ 120 "`%s' by `%s' is %s (%s), %zu LUN(s).\n", 121 dev->ddf_dev->name, 122 inquiry.product_and_revision, inquiry.vendor_id, 123 usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type), 124 inquiry.removable ? "removable" : "non-removable", 125 lun_count); 171 126 172 127 return EOK; -
uspace/drv/usbmast/mast.c
r3e4f2e0 r55054db0 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 /** Perform bulk-only mass storage reset. 142 * 143 * @param dev Device to be reseted. 144 * @return Error code. 145 */ 146 int usb_massstor_reset(usb_device_t *dev) 147 { 148 return usb_control_request_set(&dev->ctrl_pipe, 149 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 150 0xFF, 0, dev->interface_no, NULL, 0); 151 } 152 153 /** Perform complete reset recovery of bulk-only mass storage. 154 * 155 * Notice that no error is reported because if this fails, the error 156 * would reappear on next transaction somehow. 157 * 158 * @param dev Device to be reseted. 159 * @param bulk_in_idx Index of bulk in pipe. 160 * @param bulk_out_idx Index of bulk out pipe. 161 */ 162 void usb_massstor_reset_recovery(usb_device_t *dev, 163 size_t bulk_in_idx, size_t bulk_out_idx) 164 { 165 /* We would ignore errors here because if this fails 166 * we are doomed anyway and any following transaction would fail. 167 */ 168 usb_massstor_reset(dev); 169 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe); 170 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe); 171 } 172 173 /** Get max LUN of a mass storage device. 174 * 175 * @see usb_masstor_get_lun_count 176 * 177 * @warning Error from this command does not necessarily indicate malfunction 178 * of the device. Device does not need to support this request. 179 * You shall rather use usb_masstor_get_lun_count. 180 * 181 * @param dev Mass storage device. 182 * @return Error code of maximum LUN (index, not count). 183 */ 184 int usb_massstor_get_max_lun(usb_device_t *dev) 185 { 186 uint8_t max_lun; 187 size_t data_recv_len; 188 int rc = usb_control_request_get(&dev->ctrl_pipe, 189 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 190 0xFE, 0, dev->interface_no, &max_lun, 1, &data_recv_len); 191 if (rc != EOK) { 192 return rc; 193 } 194 if (data_recv_len != 1) { 195 return EEMPTY; 196 } 197 return (int) max_lun; 198 } 199 200 /** Get number of LUNs supported by mass storage device. 201 * 202 * @warning This function hides any error during the request 203 * (typically that shall not be a problem). 204 * 205 * @param dev Mass storage device. 206 * @return Number of LUNs. 207 */ 208 size_t usb_masstor_get_lun_count(usb_device_t *dev) 209 { 210 int max_lun = usb_massstor_get_max_lun(dev); 211 if (max_lun < 0) { 212 max_lun = 1; 213 } else { 214 max_lun++; 215 } 216 217 return (size_t) max_lun; 218 } 219 137 220 /** 138 221 * @} -
uspace/drv/usbmast/mast.h
r3e4f2e0 r55054db0 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 /** Result of SCSI INQUIRY command. 45 * This is already parsed structure, not the original buffer returned by 46 * the device. 47 */ 48 typedef struct { 49 /** SCSI peripheral device type. */ 50 int peripheral_device_type; 51 /** Whether the device is removable. */ 52 bool removable; 53 /** Vendor ID string. */ 54 char vendor_id[9]; 55 /** Product ID and product revision string. */ 56 char product_and_revision[12]; 57 } usb_massstor_inquiry_result_t; 58 59 int usb_massstor_data_in(usb_device_t *dev, size_t, size_t, 60 uint32_t, uint8_t, void *, size_t, void *, size_t, size_t *); 61 int usb_massstor_reset(usb_device_t *); 62 void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t); 63 int usb_massstor_get_max_lun(usb_device_t *); 64 size_t usb_masstor_get_lun_count(usb_device_t *); 65 int usb_massstor_inquiry(usb_device_t *, size_t, size_t, 66 usb_massstor_inquiry_result_t *); 67 const char *usb_str_masstor_scsi_peripheral_device_type(int); 45 68 46 69 #endif -
uspace/lib/usbdev/include/usb/request.h
r3e4f2e0 r55054db0 142 142 143 143 int usb_request_clear_endpoint_halt(usb_pipe_t *, uint16_t); 144 int usb_pipe_clear_halt(usb_pipe_t *, usb_pipe_t *); 145 int usb_request_get_endpoint_status(usb_pipe_t *, usb_pipe_t *, uint16_t *); 144 146 145 147 #endif -
uspace/lib/usbdev/src/request.c
r3e4f2e0 r55054db0 885 885 } 886 886 887 /** Clear halt bit of an endpoint pipe (after pipe stall). 888 * 889 * @param ctrl_pipe Control pipe. 890 * @param target_pipe Which pipe is halted and shall be cleared. 891 * @return Error code. 892 */ 893 int usb_pipe_clear_halt(usb_pipe_t *ctrl_pipe, usb_pipe_t *target_pipe) 894 { 895 if ((ctrl_pipe == NULL) || (target_pipe == NULL)) { 896 return EINVAL; 897 } 898 return usb_request_clear_endpoint_halt(ctrl_pipe, 899 target_pipe->endpoint_no); 900 } 901 902 /** Get endpoint status. 903 * 904 * @param[in] ctrl_pipe Control pipe. 905 * @param[in] pipe Of which pipe the status shall be received. 906 * @param[out] status Where to store pipe status (in native endianness). 907 * @return Error code. 908 */ 909 int usb_request_get_endpoint_status(usb_pipe_t *ctrl_pipe, usb_pipe_t *pipe, 910 uint16_t *status) 911 { 912 uint16_t status_tmp; 913 uint16_t pipe_index = (uint16_t) pipe->endpoint_no; 914 int rc = usb_request_get_status(ctrl_pipe, 915 USB_REQUEST_RECIPIENT_ENDPOINT, uint16_host2usb(pipe_index), 916 &status_tmp); 917 if (rc != EOK) { 918 return rc; 919 } 920 921 if (status != NULL) { 922 *status = uint16_usb2host(status_tmp); 923 } 924 925 return EOK; 926 } 927 887 928 /** 888 929 * @}
Note:
See TracChangeset
for help on using the changeset viewer.