Ignore:
File:
1 edited

Legend:

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

    r38c9505 r2aceec5  
    4545#include <errno.h>
    4646#include <str_error.h>
    47 #include "cmds.h"
    48 #include "mast.h"
     47#include "cmdw.h"
     48#include "bo_trans.h"
    4949#include "scsi_ms.h"
     50#include "usbmast.h"
    5051
    5152#define NAME "usbmast"
     
    7778};
    7879
    79 /** Mass storage function.
    80  *
    81  * Serves as soft state for function/LUN.
    82  */
    83 typedef struct {
    84         /** DDF function */
    85         ddf_fun_t *ddf_fun;
    86         /** Total number of blocks. */
    87         uint64_t nblocks;
    88         /** Block size in bytes. */
    89         size_t block_size;
    90         /** USB device function belongs to */
    91         usb_device_t *usb_dev;
    92 } usbmast_fun_t;
    93 
     80static int usbmast_fun_create(usbmast_dev_t *mdev, unsigned lun);
    9481static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
    9582    void *arg);
     
    10390{
    10491        int rc;
    105         const char *fun_name = "a";
    106         ddf_fun_t *fun = NULL;
    107         usbmast_fun_t *msfun = NULL;
     92        usbmast_dev_t *mdev = NULL;
     93        unsigned i;
    10894
    10995        /* Allocate softstate */
    110         msfun = calloc(1, sizeof(usbmast_fun_t));
    111         if (msfun == NULL) {
     96        mdev = calloc(1, sizeof(usbmast_dev_t));
     97        if (mdev == NULL) {
    11298                usb_log_error("Failed allocating softstate.\n");
    11399                rc = ENOMEM;
     
    115101        }
    116102
    117         fun = ddf_fun_create(dev->ddf_dev, fun_exposed, fun_name);
    118         if (fun == NULL) {
    119                 usb_log_error("Failed to create DDF function %s.\n", fun_name);
    120                 rc = ENOMEM;
    121                 goto error;
    122         }
    123 
    124         /* Set up a connection handler. */
    125         fun->conn_handler = usbmast_bd_connection;
    126         fun->driver_data = msfun;
     103        mdev->ddf_dev = dev->ddf_dev;
     104        mdev->usb_dev = dev;
    127105
    128106        usb_log_info("Initializing mass storage `%s'.\n",
     
    136114
    137115        usb_log_debug("Get LUN count...\n");
    138         size_t lun_count = usb_masstor_get_lun_count(dev);
    139 
    140         /* XXX Handle more than one LUN properly. */
    141         if (lun_count > 1) {
    142                 usb_log_warning ("Mass storage has %zu LUNs. Ignoring all "
    143                     "but first.\n", lun_count);
    144         }
     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;
    145177
    146178        usb_log_debug("Inquire...\n");
    147179        usbmast_inquiry_data_t inquiry;
    148         rc = usbmast_inquiry(dev, &inquiry);
     180        rc = usbmast_inquiry(mfun, &inquiry);
    149181        if (rc != EOK) {
    150182                usb_log_warning("Failed to inquire device `%s': %s.\n",
    151                     dev->ddf_dev->name, str_error(rc));
     183                    mdev->ddf_dev->name, str_error(rc));
    152184                rc = EIO;
    153185                goto error;
    154186        }
    155187
    156         usb_log_info("Mass storage `%s': " \
    157             "%s by %s rev. %s is %s (%s), %zu LUN(s).\n",
    158             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,
    159192            inquiry.product,
    160193            inquiry.vendor,
    161194            inquiry.revision,
    162195            usbmast_scsi_dev_type_str(inquiry.device_type),
    163             inquiry.removable ? "removable" : "non-removable",
    164             lun_count);
     196            inquiry.removable ? "removable" : "non-removable");
    165197
    166198        uint32_t nblocks, block_size;
    167199
    168         rc = usbmast_read_capacity(dev, &nblocks, &block_size);
     200        rc = usbmast_read_capacity(mfun, &nblocks, &block_size);
    169201        if (rc != EOK) {
    170202                usb_log_warning("Failed to read capacity, device `%s': %s.\n",
    171                     dev->ddf_dev->name, str_error(rc));
     203                    mdev->ddf_dev->name, str_error(rc));
    172204                rc = EIO;
    173205                goto error;
     
    177209            "block_size=%" PRIu32 "\n", nblocks, block_size);
    178210
    179         msfun->nblocks = nblocks;
    180         msfun->block_size = block_size;
    181         msfun->usb_dev = dev;
     211        mfun->nblocks = nblocks;
     212        mfun->block_size = block_size;
    182213
    183214        rc = ddf_fun_bind(fun);
     
    194225        if (fun != NULL)
    195226                ddf_fun_destroy(fun);
    196         if (msfun != NULL)
    197                 free(msfun);
     227        if (fun_name != NULL)
     228                free(fun_name);
     229        if (mfun != NULL)
     230                free(mfun);
    198231        return rc;
    199232}
     
    203236    void *arg)
    204237{
    205         usbmast_fun_t *msfun;
     238        usbmast_fun_t *mfun;
    206239        void *comm_buf = NULL;
    207240        size_t comm_size;
     
    229262        (void) async_share_out_finalize(callid, comm_buf);
    230263
    231         msfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
     264        mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
    232265
    233266        while (true) {
     
    243276                switch (method) {
    244277                case BD_GET_BLOCK_SIZE:
    245                         async_answer_1(callid, EOK, msfun->block_size);
     278                        async_answer_1(callid, EOK, mfun->block_size);
    246279                        break;
    247280                case BD_GET_NUM_BLOCKS:
    248                         async_answer_2(callid, EOK, LOWER32(msfun->nblocks),
    249                             UPPER32(msfun->nblocks));
     281                        async_answer_2(callid, EOK, LOWER32(mfun->nblocks),
     282                            UPPER32(mfun->nblocks));
    250283                        break;
    251284                case BD_READ_BLOCKS:
    252285                        ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    253286                        cnt = IPC_GET_ARG3(call);
    254                         retval = usbmast_read(msfun->usb_dev, ba, cnt,
    255                             msfun->block_size, comm_buf);
     287                        retval = usbmast_read(mfun, ba, cnt, comm_buf);
    256288                        async_answer_0(callid, retval);
    257289                        break;
     
    259291                        ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    260292                        cnt = IPC_GET_ARG3(call);
    261                         retval = usbmast_write(msfun->usb_dev, ba, cnt,
    262                             msfun->block_size, comm_buf);
     293                        retval = usbmast_write(mfun, ba, cnt, comm_buf);
    263294                        async_answer_0(callid, retval);
    264295                        break;
Note: See TracChangeset for help on using the changeset viewer.