Changes in / [55054db0:3e4f2e0] in mainline
- Location:
- uspace
- Files:
-
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ehci-hcd/pci.c
r55054db0 r3e4f2e0 54 54 55 55 #define CMD_OFFSET 0x0 56 #define STS_OFFSET 0x4 57 #define CFG_OFFSET 0x40 56 #define CONFIGFLAG_OFFSET 0x40 58 57 59 58 #define USBCMD_RUN 1 … … 265 264 * It would prevent pre-OS code from interfering. */ 266 265 ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 267 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 268 0xe0000000); 266 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0); 269 267 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 268 usb_log_debug("Zeroed USBLEGCTLSTS register.\n"); 270 269 271 270 /* Read again Legacy Support and Control register */ … … 292 291 volatile uint32_t *usbcmd = 293 292 (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET); 294 volatile uint32_t *usbsts =295 (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET);296 293 volatile uint32_t *usbconfigured = 297 (uint32_t*)((uint8_t*)registers + operation_offset + CFG_OFFSET); 294 (uint32_t*)((uint8_t*)registers + operation_offset 295 + CONFIGFLAG_OFFSET); 298 296 usb_log_debug("USBCMD value: %x.\n", *usbcmd); 299 297 if (*usbcmd & USBCMD_RUN) { 300 298 *usbcmd = 0; 301 while (!(*usbsts & (1 << 12))); /*wait until hc is halted */302 299 *usbconfigured = 0; 303 300 usb_log_info("EHCI turned off.\n"); … … 305 302 usb_log_info("EHCI was not running.\n"); 306 303 } 307 usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n",308 *usbcmd, *usbsts, *usbconfigured);309 304 310 305 async_hangup(parent_phone); -
uspace/drv/uhci-rhd/port.c
r55054db0 r3e4f2e0 32 32 * @brief UHCI root hub port routines 33 33 */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 35 #include <fibril_synch.h> /* async_usleep */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 36 35 #include <errno.h> 37 36 #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> /* usb_hc_new_device_wrapper */40 #include <usb/hub.h> 41 41 #include <usb/debug.h> 42 42 … … 212 212 213 213 /* 214 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3) 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 215 221 */ 216 222 { … … 223 229 port_status &= ~STATUS_IN_RESET; 224 230 uhci_port_write_status(port, port_status); 225 while (uhci_port_read_status(port) & STATUS_IN_RESET);226 // TODO: find a better way to waste time (it should be less than227 // 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 } 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 231 237 /* Enable the port. */ 232 238 uhci_port_set_enabled(port, true); 233 234 /* Reset recovery period,235 * devices do not have to respond during this period236 */237 async_usleep(10000);238 239 return EOK; 239 240 } … … 254 255 usb_log_debug("%s: Detected new device.\n", port->id_string); 255 256 256 int ret, count = 0;257 257 usb_address_t dev_addr; 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); 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); 263 261 264 262 if (ret != EOK) { … … 315 313 /* Wait for port to become enabled */ 316 314 do { 315 async_usleep(1000); 317 316 port_status = uhci_port_read_status(port); 318 317 } while ((port_status & STATUS_CONNECTED) && -
uspace/drv/usbmast/Makefile
r55054db0 r3e4f2e0 41 41 42 42 SOURCES = \ 43 inquiry.c \44 43 main.c \ 45 44 mast.c -
uspace/drv/usbmast/main.c
r55054db0 r3e4f2e0 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 35 84 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 = 0 93 }; 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 returned 116 * 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 77 138 /** Callback when new device is attached and recognized as a mass storage. 78 139 * … … 107 168 (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size); 108 169 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); 170 try_inquiry(dev); 126 171 127 172 return EOK; -
uspace/drv/usbmast/mast.c
r55054db0 r3e4f2e0 40 40 #include <str_error.h> 41 41 #include <usb/debug.h> 42 #include <usb/request.h>43 42 44 43 bool usb_mast_verbose = true; … … 64 63 * @return Error code. 65 64 */ 66 int usb_massstor_data_in(usb_device_t *dev, 67 size_t bulk_in_pipe_index, size_t bulk_out_pipe_index, 65 int usb_massstor_data_in(usb_pipe_t *bulk_in_pipe, usb_pipe_t *bulk_out_pipe, 68 66 uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size, 69 67 void *in_buffer, size_t in_buffer_size, size_t *received_size) … … 71 69 int rc; 72 70 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;75 71 76 72 /* Prepare CBW - command block wrapper */ … … 139 135 } 140 136 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 error156 * 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 fails166 * 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_count176 *177 * @warning Error from this command does not necessarily indicate malfunction178 * 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 request203 * (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 220 137 /** 221 138 * @} -
uspace/drv/usbmast/mast.h
r55054db0 r3e4f2e0 40 40 #include <usb/usb.h> 41 41 #include <usb/pipes.h> 42 #include <usb/devdrv.h>43 42 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); 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 *); 68 45 69 46 #endif -
uspace/lib/usbdev/include/usb/request.h
r55054db0 r3e4f2e0 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 *);146 144 147 145 #endif -
uspace/lib/usbdev/src/request.c
r55054db0 r3e4f2e0 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 928 887 /** 929 888 * @}
Note:
See TracChangeset
for help on using the changeset viewer.