Changeset ff65e91 in mainline
- Timestamp:
- 2011-07-06T19:45:55Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 38c9505
- Parents:
- 5e2aa83
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbmast/main.c
r5e2aa83 rff65e91 1 1 /* 2 2 * Copyright (c) 2011 Vojtech Horky 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 34 35 * Main routines of USB mass storage driver. 35 36 */ 37 #include <as.h> 38 #include <async.h> 39 #include <ipc/bd.h> 40 #include <macros.h> 36 41 #include <usb/dev/driver.h> 37 42 #include <usb/debug.h> … … 72 77 }; 73 78 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 74 97 /** Callback when new device is attached and recognized as a mass storage. 75 98 * … … 80 103 { 81 104 int rc; 82 const char *fun_name = "ctl"; 83 84 ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 85 fun_name); 86 if (ctl_fun == NULL) { 87 usb_log_error("Failed to create control function.\n"); 88 return ENOMEM; 89 } 90 rc = ddf_fun_bind(ctl_fun); 91 if (rc != EOK) { 92 usb_log_error("Failed to bind control function: %s.\n", 93 str_error(rc)); 94 return rc; 95 } 96 97 usb_log_info("Pretending to control mass storage `%s'.\n", 105 const char *fun_name = "a"; 106 ddf_fun_t *fun = NULL; 107 usbmast_fun_t *msfun = NULL; 108 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; 115 } 116 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", 98 129 dev->ddf_dev->name); 99 130 usb_log_debug(" Bulk in endpoint: %d [%zuB].\n", … … 107 138 size_t lun_count = usb_masstor_get_lun_count(dev); 108 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 } 145 109 146 usb_log_debug("Inquire...\n"); 110 147 usbmast_inquiry_data_t inquiry; … … 113 150 usb_log_warning("Failed to inquire device `%s': %s.\n", 114 151 dev->ddf_dev->name, str_error(rc)); 115 return EOK; 152 rc = EIO; 153 goto error; 116 154 } 117 155 … … 132 170 usb_log_warning("Failed to read capacity, device `%s': %s.\n", 133 171 dev->ddf_dev->name, str_error(rc)); 134 return EOK; 172 rc = EIO; 173 goto error; 135 174 } 136 175 … … 138 177 "block_size=%" PRIu32 "\n", nblocks, block_size); 139 178 140 usb_log_info("Doing test read of block 0.\n"); 141 static uint8_t bdata[512]; 142 143 rc = usbmast_read(dev, 0, 1, 512, &bdata); 179 msfun->nblocks = nblocks; 180 msfun->block_size = block_size; 181 msfun->usb_dev = dev; 182 183 rc = ddf_fun_bind(fun); 144 184 if (rc != EOK) { 145 usb_log_warning("Failed to read block 0, device `%s': %s.\n", 146 dev->ddf_dev->name, str_error(rc)); 147 return EOK; 148 } 149 150 usb_log_info("Requesting sense data.\n"); 151 static scsi_sense_data_t sdata; 152 153 rc = usbmast_request_sense(dev, &sdata, sizeof(sdata)); 154 if (rc != EOK) { 155 usb_log_warning("Failed to get sense data, device `%s': %s.\n", 156 dev->ddf_dev->name, str_error(rc)); 157 return EOK; 185 usb_log_error("Failed to bind DDF function %s: %s.\n", 186 fun_name, str_error(rc)); 187 goto error; 158 188 } 159 189 160 190 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 usb_log_debug("usbmast_bd_connection()\n"); 217 218 async_answer_0(iid, EOK); 219 220 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 221 async_answer_0(callid, EHANGUP); 222 return; 223 } 224 225 comm_buf = as_get_mappable_page(comm_size); 226 if (comm_buf == NULL) { 227 async_answer_0(callid, EHANGUP); 228 return; 229 } 230 231 (void) async_share_out_finalize(callid, comm_buf); 232 233 msfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data; 234 235 while (true) { 236 callid = async_get_call(&call); 237 method = IPC_GET_IMETHOD(call); 238 239 if (!method) { 240 /* The other side hung up. */ 241 async_answer_0(callid, EOK); 242 return; 243 } 244 245 switch (method) { 246 case BD_GET_BLOCK_SIZE: 247 async_answer_1(callid, EOK, msfun->block_size); 248 break; 249 case BD_GET_NUM_BLOCKS: 250 async_answer_2(callid, EOK, LOWER32(msfun->nblocks), 251 UPPER32(msfun->nblocks)); 252 break; 253 case BD_READ_BLOCKS: 254 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 255 cnt = IPC_GET_ARG3(call); 256 retval = usbmast_read(msfun->usb_dev, ba, cnt, 257 msfun->block_size, comm_buf); 258 async_answer_0(callid, retval); 259 break; 260 case BD_WRITE_BLOCKS: 261 usb_log_debug("usbmast_bd_connection() - BD_WRITE_BLOCKS\n"); 262 /* ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 263 cnt = IPC_GET_ARG3(call); 264 retval = 0; 265 async_answer_0(callid, retval); 266 break;*/ 267 default: 268 async_answer_0(callid, EINVAL); 269 } 270 } 161 271 } 162 272 -
uspace/lib/drv/generic/driver.c
r5e2aa83 rff65e91 314 314 " %" PRIun " was found.\n", driver->name, handle); 315 315 async_answer_0(iid, ENOENT); 316 return; 317 } 318 319 if (fun->conn_handler != NULL) { 320 /* Driver has a custom connection handler. */ 321 (*fun->conn_handler)(iid, icall, (void *)fun); 316 322 return; 317 323 } -
uspace/lib/drv/include/ddf/driver.h
r5e2aa83 rff65e91 118 118 /** Implementation of operations provided by this function */ 119 119 ddf_dev_ops_t *ops; 120 /** Connection handler or @c NULL to use the DDF default handler. */ 121 async_client_conn_t conn_handler; 120 122 121 123 /** Link in the list of functions handled by the driver */ -
uspace/srv/bd/ata_bd/ata_bd.c
r5e2aa83 rff65e91 80 80 */ 81 81 static const size_t identify_data_size = 512; 82 83 /** Size of the communication area. */84 static size_t comm_size;85 82 86 83 /** I/O base address of the command registers. */ … … 281 278 sysarg_t method; 282 279 devmap_handle_t dh; 280 size_t comm_size; /**< Size of the communication area. */ 283 281 unsigned int flags; 284 282 int retval;
Note:
See TracChangeset
for help on using the changeset viewer.