Changes in uspace/drv/bus/usb/usbmast/main.c [38c9505:5203e256] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbmast/main.c
r38c9505 r5203e256 1 1 /* 2 2 * Copyright (c) 2011 Vojtech Horky 3 * Copyright (c) 2011 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 35 34 * Main routines of USB mass storage driver. 36 35 */ 37 #include <as.h>38 #include <async.h>39 #include <ipc/bd.h>40 #include <macros.h>41 36 #include <usb/dev/driver.h> 42 37 #include <usb/debug.h> … … 46 41 #include <str_error.h> 47 42 #include "cmds.h" 43 #include "scsi.h" 48 44 #include "mast.h" 49 #include "scsi_ms.h"50 45 51 46 #define NAME "usbmast" 47 48 #define BULK_IN_EP 0 49 #define BULK_OUT_EP 1 52 50 53 51 #define GET_BULK_IN(dev) ((dev)->pipes[BULK_IN_EP].pipe) … … 77 75 }; 78 76 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 94 static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,95 void *arg);96 97 77 /** Callback when new device is attached and recognized as a mass storage. 98 78 * … … 103 83 { 104 84 int rc; 105 const char *fun_name = "a"; 106 ddf_fun_t *fun = NULL; 107 usbmast_fun_t *msfun = NULL; 85 const char *fun_name = "ctl"; 108 86 109 /* Allocate softstate */ 110 msfun = calloc(1, sizeof(usbmast_fun_t)); 111 if (msfun == NULL) { 112 usb_log_error("Failed allocating softstate.\n"); 113 rc = ENOMEM; 114 goto error; 87 ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 88 fun_name); 89 if (ctl_fun == NULL) { 90 usb_log_error("Failed to create control function.\n"); 91 return ENOMEM; 92 } 93 rc = ddf_fun_bind(ctl_fun); 94 if (rc != EOK) { 95 usb_log_error("Failed to bind control function: %s.\n", 96 str_error(rc)); 97 return rc; 115 98 } 116 99 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; 127 128 usb_log_info("Initializing mass storage `%s'.\n", 100 usb_log_info("Pretending to control mass storage `%s'.\n", 129 101 dev->ddf_dev->name); 130 102 usb_log_debug(" Bulk in endpoint: %d [%zuB].\n", … … 135 107 (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size); 136 108 137 usb_log_debug("Get LUN count...\n");138 109 size_t lun_count = usb_masstor_get_lun_count(dev); 139 110 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 } 145 146 usb_log_debug("Inquire...\n"); 147 usbmast_inquiry_data_t inquiry; 148 rc = usbmast_inquiry(dev, &inquiry); 111 usb_massstor_inquiry_result_t inquiry; 112 rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry); 149 113 if (rc != EOK) { 150 usb_log_warning("Failed to inquir edevice `%s': %s.\n",114 usb_log_warning("Failed to inquiry device `%s': %s.\n", 151 115 dev->ddf_dev->name, str_error(rc)); 152 rc = EIO; 153 goto error; 116 return EOK; 154 117 } 155 118 156 119 usb_log_info("Mass storage `%s': " \ 157 " %s by %s rev. %sis %s (%s), %zu LUN(s).\n",120 "`%s' by `%s' is %s (%s), %zu LUN(s).\n", 158 121 dev->ddf_dev->name, 159 inquiry.product, 160 inquiry.vendor, 161 inquiry.revision, 162 usbmast_scsi_dev_type_str(inquiry.device_type), 122 inquiry.product_and_revision, inquiry.vendor_id, 123 usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type), 163 124 inquiry.removable ? "removable" : "non-removable", 164 125 lun_count); 165 126 166 uint32_t nblocks, block_size;167 168 rc = usbmast_read_capacity(dev, &nblocks, &block_size);169 if (rc != EOK) {170 usb_log_warning("Failed to read capacity, device `%s': %s.\n",171 dev->ddf_dev->name, str_error(rc));172 rc = EIO;173 goto error;174 }175 176 usb_log_info("Read Capacity: nblocks=%" PRIu32 ", "177 "block_size=%" PRIu32 "\n", nblocks, block_size);178 179 msfun->nblocks = nblocks;180 msfun->block_size = block_size;181 msfun->usb_dev = dev;182 183 rc = ddf_fun_bind(fun);184 if (rc != EOK) {185 usb_log_error("Failed to bind DDF function %s: %s.\n",186 fun_name, str_error(rc));187 goto error;188 }189 190 127 return EOK; 191 192 /* Error cleanup */193 error:194 if (fun != NULL)195 ddf_fun_destroy(fun);196 if (msfun != NULL)197 free(msfun);198 return rc;199 }200 201 /** Blockdev client connection handler. */202 static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,203 void *arg)204 {205 usbmast_fun_t *msfun;206 void *comm_buf = NULL;207 size_t comm_size;208 ipc_callid_t callid;209 ipc_call_t call;210 unsigned int flags;211 sysarg_t method;212 uint64_t ba;213 size_t cnt;214 int retval;215 216 async_answer_0(iid, EOK);217 218 if (!async_share_out_receive(&callid, &comm_size, &flags)) {219 async_answer_0(callid, EHANGUP);220 return;221 }222 223 comm_buf = as_get_mappable_page(comm_size);224 if (comm_buf == NULL) {225 async_answer_0(callid, EHANGUP);226 return;227 }228 229 (void) async_share_out_finalize(callid, comm_buf);230 231 msfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;232 233 while (true) {234 callid = async_get_call(&call);235 method = IPC_GET_IMETHOD(call);236 237 if (!method) {238 /* The other side hung up. */239 async_answer_0(callid, EOK);240 return;241 }242 243 switch (method) {244 case BD_GET_BLOCK_SIZE:245 async_answer_1(callid, EOK, msfun->block_size);246 break;247 case BD_GET_NUM_BLOCKS:248 async_answer_2(callid, EOK, LOWER32(msfun->nblocks),249 UPPER32(msfun->nblocks));250 break;251 case BD_READ_BLOCKS:252 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));253 cnt = IPC_GET_ARG3(call);254 retval = usbmast_read(msfun->usb_dev, ba, cnt,255 msfun->block_size, comm_buf);256 async_answer_0(callid, retval);257 break;258 case BD_WRITE_BLOCKS:259 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));260 cnt = IPC_GET_ARG3(call);261 retval = usbmast_write(msfun->usb_dev, ba, cnt,262 msfun->block_size, comm_buf);263 async_answer_0(callid, retval);264 break;265 default:266 async_answer_0(callid, EINVAL);267 }268 }269 128 } 270 129
Note:
See TracChangeset
for help on using the changeset viewer.