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

Changeset 2aceec5 in mainline


Ignore:
Timestamp:
2011-07-15T21:24:35Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
4118f5f, 8ad496d
Parents:
e6b32a8
Message:

Support multiple LUNs in mass storage driver.

Location:
uspace/drv/bus/usb/usbmast
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbmast/bo_trans.c

    re6b32a8 r2aceec5  
    7373        int rc;
    7474        size_t act_size;
    75         usb_pipe_t *bulk_in_pipe = mfun->usb_dev->pipes[BULK_IN_EP].pipe;
    76         usb_pipe_t *bulk_out_pipe = mfun->usb_dev->pipes[BULK_OUT_EP].pipe;
     75        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
     76        usb_pipe_t *bulk_out_pipe = mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe;
    7777
    7878        /* Prepare CBW - command block wrapper */
     
    209209 * @return              Error code
    210210 */
    211 int usb_massstor_reset(usbmast_fun_t *mfun)
    212 {
    213         return usb_control_request_set(&mfun->usb_dev->ctrl_pipe,
     211int usb_massstor_reset(usbmast_dev_t *mdev)
     212{
     213        return usb_control_request_set(&mdev->usb_dev->ctrl_pipe,
    214214            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    215             0xFF, 0, mfun->usb_dev->interface_no, NULL, 0);
     215            0xFF, 0, mdev->usb_dev->interface_no, NULL, 0);
    216216}
    217217
     
    223223 * @param mfun          Mass storage function
    224224 */
    225 void usb_massstor_reset_recovery(usbmast_fun_t *mfun)
     225void usb_massstor_reset_recovery(usbmast_dev_t *mdev)
    226226{
    227227        /* We would ignore errors here because if this fails
    228228         * we are doomed anyway and any following transaction would fail.
    229229         */
    230         usb_massstor_reset(mfun);
    231         usb_pipe_clear_halt(&mfun->usb_dev->ctrl_pipe,
    232             mfun->usb_dev->pipes[BULK_IN_EP].pipe);
    233         usb_pipe_clear_halt(&mfun->usb_dev->ctrl_pipe,
    234             mfun->usb_dev->pipes[BULK_OUT_EP].pipe);
     230        usb_massstor_reset(mdev);
     231        usb_pipe_clear_halt(&mdev->usb_dev->ctrl_pipe,
     232            mdev->usb_dev->pipes[BULK_IN_EP].pipe);
     233        usb_pipe_clear_halt(&mdev->usb_dev->ctrl_pipe,
     234            mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
    235235}
    236236
     
    246246 * @return              Error code of maximum LUN (index, not count)
    247247 */
    248 int usb_massstor_get_max_lun(usbmast_fun_t *mfun)
     248int usb_massstor_get_max_lun(usbmast_dev_t *mdev)
    249249{
    250250        uint8_t max_lun;
    251251        size_t data_recv_len;
    252         int rc = usb_control_request_get(&mfun->usb_dev->ctrl_pipe,
     252        int rc = usb_control_request_get(&mdev->usb_dev->ctrl_pipe,
    253253            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    254             0xFE, 0, mfun->usb_dev->interface_no, &max_lun, 1, &data_recv_len);
     254            0xFE, 0, mdev->usb_dev->interface_no, &max_lun, 1, &data_recv_len);
    255255        if (rc != EOK) {
    256256                return rc;
     
    270270 * @return              Number of LUNs
    271271 */
    272 size_t usb_masstor_get_lun_count(usbmast_fun_t *mfun)
    273 {
    274         int max_lun = usb_massstor_get_max_lun(mfun);
     272size_t usb_masstor_get_lun_count(usbmast_dev_t *mdev)
     273{
     274        int max_lun = usb_massstor_get_max_lun(mdev);
    275275        if (max_lun < 0) {
    276276                max_lun = 1;
  • uspace/drv/bus/usb/usbmast/bo_trans.h

    re6b32a8 r2aceec5  
    5151extern int usb_massstor_data_out(usbmast_fun_t *, uint32_t, const void *,
    5252    size_t, const void *, size_t, size_t *);
    53 extern int usb_massstor_reset(usbmast_fun_t *);
    54 extern void usb_massstor_reset_recovery(usbmast_fun_t *);
    55 extern int usb_massstor_get_max_lun(usbmast_fun_t *);
    56 extern size_t usb_masstor_get_lun_count(usbmast_fun_t *);
     53extern int usb_massstor_reset(usbmast_dev_t *);
     54extern void usb_massstor_reset_recovery(usbmast_dev_t *);
     55extern int usb_massstor_get_max_lun(usbmast_dev_t *);
     56extern size_t usb_masstor_get_lun_count(usbmast_dev_t *);
    5757
    5858#endif
  • uspace/drv/bus/usb/usbmast/main.c

    re6b32a8 r2aceec5  
    7878};
    7979
     80static int usbmast_fun_create(usbmast_dev_t *mdev, unsigned lun);
    8081static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
    8182    void *arg);
     
    8990{
    9091        int rc;
    91         const char *fun_name = "a";
    92         ddf_fun_t *fun = NULL;
    93         usbmast_fun_t *msfun = NULL;
     92        usbmast_dev_t *mdev = NULL;
     93        unsigned i;
    9494
    9595        /* Allocate softstate */
    96         msfun = calloc(1, sizeof(usbmast_fun_t));
    97         if (msfun == NULL) {
     96        mdev = calloc(1, sizeof(usbmast_dev_t));
     97        if (mdev == NULL) {
    9898                usb_log_error("Failed allocating softstate.\n");
    9999                rc = ENOMEM;
     
    101101        }
    102102
    103         msfun->usb_dev = dev;
    104         msfun->lun = 0;
    105 
    106         fun = ddf_fun_create(dev->ddf_dev, fun_exposed, fun_name);
    107         if (fun == NULL) {
    108                 usb_log_error("Failed to create DDF function %s.\n", fun_name);
    109                 rc = ENOMEM;
    110                 goto error;
    111         }
    112 
    113         /* Set up a connection handler. */
    114         fun->conn_handler = usbmast_bd_connection;
    115         fun->driver_data = msfun;
     103        mdev->ddf_dev = dev->ddf_dev;
     104        mdev->usb_dev = dev;
    116105
    117106        usb_log_info("Initializing mass storage `%s'.\n",
     
    125114
    126115        usb_log_debug("Get LUN count...\n");
    127         size_t lun_count = usb_masstor_get_lun_count(msfun);
    128 
    129         /* XXX Handle more than one LUN properly. */
    130         if (lun_count > 1) {
    131                 usb_log_warning ("Mass storage has %zu LUNs. Ignoring all "
    132                     "but first.\n", lun_count);
    133         }
     116        mdev->luns = usb_masstor_get_lun_count(mdev);
     117
     118        for (i = 0; i < mdev->luns; i++) {
     119                rc = usbmast_fun_create(mdev, i);
     120                if (rc != EOK)
     121                        goto error;
     122        }
     123
     124        return EOK;
     125error:
     126        /* XXX Destroy functions */
     127        if (mdev != NULL)
     128                free(mdev);
     129        return rc;
     130}
     131
     132/** Create mass storage function.
     133 *
     134 * Called once for each LUN.
     135 *
     136 * @param mdev          Mass storage device
     137 * @param lun           LUN
     138 * @return              EOK on success or negative error code.
     139 */
     140static int usbmast_fun_create(usbmast_dev_t *mdev, unsigned lun)
     141{
     142        int rc;
     143        char *fun_name = NULL;
     144        ddf_fun_t *fun = NULL;
     145        usbmast_fun_t *mfun = NULL;
     146
     147        /* Allocate softstate */
     148        mfun = calloc(1, sizeof(usbmast_fun_t));
     149        if (mfun == NULL) {
     150                usb_log_error("Failed allocating softstate.\n");
     151                rc = ENOMEM;
     152                goto error;
     153        }
     154
     155        mfun->mdev = mdev;
     156        mfun->lun = lun;
     157
     158        if (asprintf(&fun_name, "l%u", lun) < 0) {
     159                usb_log_error("Out of memory.\n");
     160                rc = ENOMEM;
     161                goto error;
     162        }
     163
     164        fun = ddf_fun_create(mdev->ddf_dev, fun_exposed, fun_name);
     165        if (fun == NULL) {
     166                usb_log_error("Failed to create DDF function %s.\n", fun_name);
     167                rc = ENOMEM;
     168                goto error;
     169        }
     170
     171        free(fun_name);
     172        fun_name = NULL;
     173
     174        /* Set up a connection handler. */
     175        fun->conn_handler = usbmast_bd_connection;
     176        fun->driver_data = mfun;
    134177
    135178        usb_log_debug("Inquire...\n");
    136179        usbmast_inquiry_data_t inquiry;
    137         rc = usbmast_inquiry(msfun, &inquiry);
     180        rc = usbmast_inquiry(mfun, &inquiry);
    138181        if (rc != EOK) {
    139182                usb_log_warning("Failed to inquire device `%s': %s.\n",
    140                     dev->ddf_dev->name, str_error(rc));
     183                    mdev->ddf_dev->name, str_error(rc));
    141184                rc = EIO;
    142185                goto error;
    143186        }
    144187
    145         usb_log_info("Mass storage `%s': " \
    146             "%s by %s rev. %s is %s (%s), %zu LUN(s).\n",
    147             dev->ddf_dev->name,
     188        usb_log_info("Mass storage `%s' LUN %u: " \
     189            "%s by %s rev. %s is %s (%s).\n",
     190            mdev->ddf_dev->name,
     191            lun,
    148192            inquiry.product,
    149193            inquiry.vendor,
    150194            inquiry.revision,
    151195            usbmast_scsi_dev_type_str(inquiry.device_type),
    152             inquiry.removable ? "removable" : "non-removable",
    153             lun_count);
     196            inquiry.removable ? "removable" : "non-removable");
    154197
    155198        uint32_t nblocks, block_size;
    156199
    157         rc = usbmast_read_capacity(msfun, &nblocks, &block_size);
     200        rc = usbmast_read_capacity(mfun, &nblocks, &block_size);
    158201        if (rc != EOK) {
    159202                usb_log_warning("Failed to read capacity, device `%s': %s.\n",
    160                     dev->ddf_dev->name, str_error(rc));
     203                    mdev->ddf_dev->name, str_error(rc));
    161204                rc = EIO;
    162205                goto error;
     
    166209            "block_size=%" PRIu32 "\n", nblocks, block_size);
    167210
    168         msfun->nblocks = nblocks;
    169         msfun->block_size = block_size;
     211        mfun->nblocks = nblocks;
     212        mfun->block_size = block_size;
    170213
    171214        rc = ddf_fun_bind(fun);
     
    182225        if (fun != NULL)
    183226                ddf_fun_destroy(fun);
    184         if (msfun != NULL)
    185                 free(msfun);
     227        if (fun_name != NULL)
     228                free(fun_name);
     229        if (mfun != NULL)
     230                free(mfun);
    186231        return rc;
    187232}
     
    191236    void *arg)
    192237{
    193         usbmast_fun_t *msfun;
     238        usbmast_fun_t *mfun;
    194239        void *comm_buf = NULL;
    195240        size_t comm_size;
     
    217262        (void) async_share_out_finalize(callid, comm_buf);
    218263
    219         msfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
     264        mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
    220265
    221266        while (true) {
     
    231276                switch (method) {
    232277                case BD_GET_BLOCK_SIZE:
    233                         async_answer_1(callid, EOK, msfun->block_size);
     278                        async_answer_1(callid, EOK, mfun->block_size);
    234279                        break;
    235280                case BD_GET_NUM_BLOCKS:
    236                         async_answer_2(callid, EOK, LOWER32(msfun->nblocks),
    237                             UPPER32(msfun->nblocks));
     281                        async_answer_2(callid, EOK, LOWER32(mfun->nblocks),
     282                            UPPER32(mfun->nblocks));
    238283                        break;
    239284                case BD_READ_BLOCKS:
    240285                        ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    241286                        cnt = IPC_GET_ARG3(call);
    242                         retval = usbmast_read(msfun, ba, cnt, comm_buf);
     287                        retval = usbmast_read(mfun, ba, cnt, comm_buf);
    243288                        async_answer_0(callid, retval);
    244289                        break;
     
    246291                        ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    247292                        cnt = IPC_GET_ARG3(call);
    248                         retval = usbmast_write(msfun, ba, cnt, comm_buf);
     293                        retval = usbmast_write(mfun, ba, cnt, comm_buf);
    249294                        async_answer_0(callid, retval);
    250295                        break;
  • uspace/drv/bus/usb/usbmast/scsi_ms.c

    re6b32a8 r2aceec5  
    8383        if (rc != EOK) {
    8484                usb_log_error("Inquiry failed, device %s: %s.\n",
    85                    mfun->usb_dev->ddf_dev->name, str_error(rc));
     85                   mfun->mdev->ddf_dev->name, str_error(rc));
    8686                return rc;
    8787        }
     
    140140        if (rc != EOK) {
    141141                usb_log_error("Request Sense failed, device %s: %s.\n",
    142                    mfun->usb_dev->ddf_dev->name, str_error(rc));
     142                   mfun->mdev->ddf_dev->name, str_error(rc));
    143143                return rc;
    144144        }
     
    177177        if (rc != EOK) {
    178178                usb_log_error("Read Capacity (10) failed, device %s: %s.\n",
    179                    mfun->usb_dev->ddf_dev->name, str_error(rc));
     179                   mfun->mdev->ddf_dev->name, str_error(rc));
    180180                return rc;
    181181        }
     
    225225        if (rc != EOK) {
    226226                usb_log_error("Read (12) failed, device %s: %s.\n",
    227                    mfun->usb_dev->ddf_dev->name, str_error(rc));
     227                   mfun->mdev->ddf_dev->name, str_error(rc));
    228228                return rc;
    229229        }
     
    270270        if (rc != EOK) {
    271271                usb_log_error("Write (12) failed, device %s: %s.\n",
    272                    mfun->usb_dev->ddf_dev->name, str_error(rc));
     272                   mfun->mdev->ddf_dev->name, str_error(rc));
    273273                return rc;
    274274        }
  • uspace/drv/bus/usb/usbmast/usbmast.h

    re6b32a8 r2aceec5  
    4040#include <usb/usb.h>
    4141
     42/** Mass storage device. */
     43typedef struct {
     44        /** DDF device */
     45        ddf_dev_t *ddf_dev;
     46        /** USB device */
     47        usb_device_t *usb_dev;
     48        /** Number of LUNs */
     49        unsigned luns;
     50} usbmast_dev_t;
     51
    4252/** Mass storage function.
    4353 *
     
    4555 */
    4656typedef struct {
     57        /** Mass storage device the function belongs to */
     58        usbmast_dev_t *mdev;
    4759        /** DDF function */
    4860        ddf_fun_t *ddf_fun;
    4961        /** LUN */
    5062        unsigned lun;
    51         /** Total number of blocks. */
     63        /** Total number of blocks */
    5264        uint64_t nblocks;
    53         /** Block size in bytes. */
     65        /** Block size in bytes */
    5466        size_t block_size;
    55         /** USB device function belongs to */
    56         usb_device_t *usb_dev;
    5767} usbmast_fun_t;
    5868
Note: See TracChangeset for help on using the changeset viewer.