Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 55054db0 in mainline


Ignore:
Timestamp:
2011-05-13T13:44:19Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
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.
Message:

Merge development/ changes

Location:
uspace
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ehci-hcd/pci.c

    r3e4f2e0 r55054db0  
    5454
    5555#define CMD_OFFSET 0x0
    56 #define CONFIGFLAG_OFFSET 0x40
     56#define STS_OFFSET 0x4
     57#define CFG_OFFSET 0x40
    5758
    5859#define USBCMD_RUN 1
     
    264265         * It would prevent pre-OS code from interfering. */
    265266        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);
    267269        CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
    268         usb_log_debug("Zeroed USBLEGCTLSTS register.\n");
    269270
    270271        /* Read again Legacy Support and Control register */
     
    291292        volatile uint32_t *usbcmd =
    292293            (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET);
     294        volatile uint32_t *usbsts =
     295            (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET);
    293296        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);
    296298        usb_log_debug("USBCMD value: %x.\n", *usbcmd);
    297299        if (*usbcmd & USBCMD_RUN) {
    298300                *usbcmd = 0;
     301                while (!(*usbsts & (1 << 12))); /*wait until hc is halted */
    299302                *usbconfigured = 0;
    300303                usb_log_info("EHCI turned off.\n");
     
    302305                usb_log_info("EHCI was not running.\n");
    303306        }
     307        usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n",
     308            *usbcmd, *usbsts, *usbconfigured);
    304309
    305310        async_hangup(parent_phone);
  • uspace/drv/uhci-rhd/port.c

    r3e4f2e0 r55054db0  
    3232 * @brief UHCI root hub port routines
    3333 */
    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 */
    3536#include <errno.h>
    3637#include <str_error.h>
    37 #include <fibril_synch.h>
    3838
    3939#include <usb/usb.h>    /* usb_address_t */
    40 #include <usb/hub.h>
     40#include <usb/hub.h>    /* usb_hc_new_device_wrapper */
    4141#include <usb/debug.h>
    4242
     
    212212
    213213        /*
    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)
    221215         */
    222216        {
     
    229223                port_status &= ~STATUS_IN_RESET;
    230224                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        }
    237231        /* Enable the port. */
    238232        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);
    239238        return EOK;
    240239}
     
    255254        usb_log_debug("%s: Detected new device.\n", port->id_string);
    256255
     256        int ret, count = 0;
    257257        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);
    261263
    262264        if (ret != EOK) {
     
    313315        /* Wait for port to become enabled */
    314316        do {
    315                 async_usleep(1000);
    316317                port_status = uhci_port_read_status(port);
    317318        } while ((port_status & STATUS_CONNECTED) &&
  • uspace/drv/usbmast/Makefile

    r3e4f2e0 r55054db0  
    4141
    4242SOURCES = \
     43        inquiry.c \
    4344        main.c \
    4445        mast.c
  • uspace/drv/usbmast/main.c

    r3e4f2e0 r55054db0  
    7575};
    7676
    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 
    13877/** Callback when new device is attached and recognized as a mass storage.
    13978 *
     
    168107            (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size);
    169108
    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);
    171126
    172127        return EOK;
  • uspace/drv/usbmast/mast.c

    r3e4f2e0 r55054db0  
    4040#include <str_error.h>
    4141#include <usb/debug.h>
     42#include <usb/request.h>
    4243
    4344bool usb_mast_verbose = true;
     
    6364 * @return Error code.
    6465 */
    65 int usb_massstor_data_in(usb_pipe_t *bulk_in_pipe, usb_pipe_t *bulk_out_pipe,
     66int usb_massstor_data_in(usb_device_t *dev,
     67    size_t bulk_in_pipe_index, size_t bulk_out_pipe_index,
    6668    uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size,
    6769    void *in_buffer, size_t in_buffer_size, size_t *received_size)
     
    6971        int rc;
    7072        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;
    7175
    7276        /* Prepare CBW - command block wrapper */
     
    135139}
    136140
     141/** Perform bulk-only mass storage reset.
     142 *
     143 * @param dev Device to be reseted.
     144 * @return Error code.
     145 */
     146int 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 */
     162void 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 */
     184int 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 */
     208size_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
    137220/**
    138221 * @}
  • uspace/drv/usbmast/mast.h

    r3e4f2e0 r55054db0  
    4040#include <usb/usb.h>
    4141#include <usb/pipes.h>
     42#include <usb/devdrv.h>
    4243
    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 */
     48typedef 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
     59int 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 *);
     61int usb_massstor_reset(usb_device_t *);
     62void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t);
     63int usb_massstor_get_max_lun(usb_device_t *);
     64size_t usb_masstor_get_lun_count(usb_device_t *);
     65int usb_massstor_inquiry(usb_device_t *, size_t, size_t,
     66    usb_massstor_inquiry_result_t *);
     67const char *usb_str_masstor_scsi_peripheral_device_type(int);
    4568
    4669#endif
  • uspace/lib/usbdev/include/usb/request.h

    r3e4f2e0 r55054db0  
    142142
    143143int usb_request_clear_endpoint_halt(usb_pipe_t *, uint16_t);
     144int usb_pipe_clear_halt(usb_pipe_t *, usb_pipe_t *);
     145int usb_request_get_endpoint_status(usb_pipe_t *, usb_pipe_t *, uint16_t *);
    144146
    145147#endif
  • uspace/lib/usbdev/src/request.c

    r3e4f2e0 r55054db0  
    885885}
    886886
     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 */
     893int 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 */
     909int 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
    887928/**
    888929 * @}
Note: See TracChangeset for help on using the changeset viewer.