Changeset 84439d7 in mainline for uspace/lib/drv
- Timestamp:
- 2010-12-05T09:34:46Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 75732da
- Parents:
- 56b962d (diff), 35537a7 (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. - Location:
- uspace/lib/drv
- Files:
-
- 3 edited
-
generic/driver.c (modified) (6 diffs)
-
generic/remote_usbhc.c (modified) (8 diffs)
-
include/usbhc_iface.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r56b962d r84439d7 48 48 #include <ctype.h> 49 49 #include <errno.h> 50 #include <inttypes.h> 50 51 51 52 #include <ipc/driver.h> … … 164 165 165 166 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 167 devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall); 168 166 169 device_t *dev = create_device(); 167 170 dev->handle = dev_handle; … … 171 174 172 175 add_to_devices_list(dev); 176 dev->parent = driver_get_device(&devices, parent_dev_handle); 177 173 178 res = driver->driver_ops->add_device(dev); 174 179 if (0 == res) { 175 printf("%s: new device with handle = %xwas added.\n",180 printf("%s: new device with handle=%" PRIun " was added.\n", 176 181 driver->name, dev_handle); 177 182 } else { 178 printf("%s: failed to add a new device with handle = % d.\n",183 printf("%s: failed to add a new device with handle = %" PRIun ".\n", 179 184 driver->name, dev_handle); 180 185 remove_from_devices_list(dev); … … 203 208 break; 204 209 default: 205 if (!(callid & IPC_CALLID_NOTIFICATION)) 206 ipc_answer_0(callid, ENOENT); 210 ipc_answer_0(callid, ENOENT); 207 211 } 208 212 } … … 226 230 if (dev == NULL) { 227 231 printf("%s: driver_connection_gen error - no device with handle" 228 " % xwas found.\n", driver->name, handle);232 " %" PRIun " was found.\n", driver->name, handle); 229 233 ipc_answer_0(iid, ENOENT); 230 234 return; … … 290 294 printf("%s: driver_connection_gen error - ", 291 295 driver->name); 292 printf("device with handle % dhas no interface "296 printf("device with handle %" PRIun " has no interface " 293 297 "with id %d.\n", handle, iface_idx); 294 298 ipc_answer_0(callid, ENOTSUP); -
uspace/lib/drv/generic/remote_usbhc.c
r56b962d r84439d7 42 42 #define USB_MAX_PAYLOAD_SIZE 1020 43 43 44 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 45 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 46 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 46 47 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 //static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 51 static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 52 static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 53 static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 54 static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 55 static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 56 static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 57 static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 58 static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 59 //static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 60 49 61 /** Remote USB interface operations. */ 50 62 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 51 &remote_usbhc_get_buffer, 52 &remote_usbhc_interrupt_out, 53 &remote_usbhc_interrupt_in 63 remote_usbhc_get_address, 64 65 remote_usbhc_get_buffer, 66 67 remote_usbhc_reserve_default_address, 68 remote_usbhc_release_default_address, 69 70 remote_usbhc_request_address, 71 remote_usbhc_bind_address, 72 remote_usbhc_release_address, 73 74 remote_usbhc_interrupt_out, 75 remote_usbhc_interrupt_in, 76 77 remote_usbhc_control_write_setup, 78 remote_usbhc_control_write_data, 79 remote_usbhc_control_write_status, 80 81 remote_usbhc_control_read_setup, 82 remote_usbhc_control_read_data, 83 remote_usbhc_control_read_status 54 84 }; 55 85 … … 68 98 } async_transaction_t; 69 99 100 void remote_usbhc_get_address(device_t *device, void *iface, 101 ipc_callid_t callid, ipc_call_t *call) 102 { 103 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 104 105 if (!usb_iface->tell_address) { 106 ipc_answer_0(callid, ENOTSUP); 107 return; 108 } 109 110 devman_handle_t handle = IPC_GET_ARG1(*call); 111 112 usb_address_t address; 113 int rc = usb_iface->tell_address(device, handle, &address); 114 if (rc != EOK) { 115 ipc_answer_0(callid, rc); 116 } else { 117 ipc_answer_1(callid, EOK, address); 118 } 119 } 70 120 71 121 void remote_usbhc_get_buffer(device_t *device, void *iface, … … 102 152 } 103 153 154 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 155 ipc_callid_t callid, ipc_call_t *call) 156 { 157 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 158 159 if (!usb_iface->reserve_default_address) { 160 ipc_answer_0(callid, ENOTSUP); 161 return; 162 } 163 164 int rc = usb_iface->reserve_default_address(device); 165 166 ipc_answer_0(callid, rc); 167 } 168 169 void remote_usbhc_release_default_address(device_t *device, void *iface, 170 ipc_callid_t callid, ipc_call_t *call) 171 { 172 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 173 174 if (!usb_iface->release_default_address) { 175 ipc_answer_0(callid, ENOTSUP); 176 return; 177 } 178 179 int rc = usb_iface->release_default_address(device); 180 181 ipc_answer_0(callid, rc); 182 } 183 184 void remote_usbhc_request_address(device_t *device, void *iface, 185 ipc_callid_t callid, ipc_call_t *call) 186 { 187 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 188 189 if (!usb_iface->request_address) { 190 ipc_answer_0(callid, ENOTSUP); 191 return; 192 } 193 194 usb_address_t address; 195 int rc = usb_iface->request_address(device, &address); 196 if (rc != EOK) { 197 ipc_answer_0(callid, rc); 198 } else { 199 ipc_answer_1(callid, EOK, (ipcarg_t) address); 200 } 201 } 202 203 void remote_usbhc_bind_address(device_t *device, void *iface, 204 ipc_callid_t callid, ipc_call_t *call) 205 { 206 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 207 208 if (!usb_iface->bind_address) { 209 ipc_answer_0(callid, ENOTSUP); 210 return; 211 } 212 213 usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call); 214 devman_handle_t handle = (devman_handle_t) IPC_GET_ARG2(*call); 215 216 int rc = usb_iface->bind_address(device, address, handle); 217 218 ipc_answer_0(callid, rc); 219 } 220 221 void remote_usbhc_release_address(device_t *device, void *iface, 222 ipc_callid_t callid, ipc_call_t *call) 223 { 224 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 225 226 if (!usb_iface->release_address) { 227 ipc_answer_0(callid, ENOTSUP); 228 return; 229 } 230 231 usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call); 232 233 int rc = usb_iface->release_address(device, address); 234 235 ipc_answer_0(callid, rc); 236 } 237 104 238 105 239 static void callback_out(device_t *device, … … 125 259 } 126 260 127 void remote_usbhc_interrupt_out(device_t *device, void *iface, 128 ipc_callid_t callid, ipc_call_t *call) 129 { 130 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 261 /** Process an outgoing transfer (both OUT and SETUP). 262 * 263 * @param device Target device. 264 * @param callid Initiating caller. 265 * @param call Initiating call. 266 * @param transfer_func Transfer function (might be NULL). 267 */ 268 static void remote_usbhc_out_transfer(device_t *device, 269 ipc_callid_t callid, ipc_call_t *call, 270 usbhc_iface_transfer_out_t transfer_func) 271 { 272 if (!transfer_func) { 273 ipc_answer_0(callid, ENOTSUP); 274 return; 275 } 131 276 132 277 size_t expected_len = IPC_GET_ARG3(*call); … … 149 294 } 150 295 151 if (!usb_iface->interrupt_out) {152 ipc_answer_0(callid, ENOTSUP);153 return;154 }155 156 296 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 157 297 trans->caller = callid; 158 trans->buffer = NULL;159 trans->size = 0;160 161 int rc = usb_iface->interrupt_out(device, target, buffer, len,298 trans->buffer = buffer; 299 trans->size = len; 300 301 int rc = transfer_func(device, target, buffer, len, 162 302 callback_out, trans); 163 303 164 304 if (rc != EOK) { 165 305 ipc_answer_0(callid, rc); 306 if (buffer != NULL) { 307 free(buffer); 308 } 166 309 free(trans); 167 310 } 168 311 } 169 312 170 void remote_usbhc_interrupt_in(device_t *device, void *iface, 171 ipc_callid_t callid, ipc_call_t *call) 172 { 173 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 313 /** Process an incoming transfer. 314 * 315 * @param device Target device. 316 * @param callid Initiating caller. 317 * @param call Initiating call. 318 * @param transfer_func Transfer function (might be NULL). 319 */ 320 static void remote_usbhc_in_transfer(device_t *device, 321 ipc_callid_t callid, ipc_call_t *call, 322 usbhc_iface_transfer_in_t transfer_func) 323 { 324 if (!transfer_func) { 325 ipc_answer_0(callid, ENOTSUP); 326 return; 327 } 174 328 175 329 size_t len = IPC_GET_ARG3(*call); … … 179 333 }; 180 334 181 if (!usb_iface->interrupt_in) {182 ipc_answer_0(callid, ENOTSUP);183 return;184 }185 186 335 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 187 336 trans->caller = callid; … … 189 338 trans->size = len; 190 339 191 int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,340 int rc = transfer_func(device, target, trans->buffer, len, 192 341 callback_in, trans); 193 342 … … 199 348 } 200 349 350 /** Process status part of control transfer. 351 * 352 * @param device Target device. 353 * @param callid Initiating caller. 354 * @param call Initiating call. 355 * @param direction Transfer direction (read ~ in, write ~ out). 356 * @param transfer_in_func Transfer function for control read (might be NULL). 357 * @param transfer_out_func Transfer function for control write (might be NULL). 358 */ 359 static void remote_usbhc_status_transfer(device_t *device, 360 ipc_callid_t callid, ipc_call_t *call, 361 usb_direction_t direction, 362 int (*transfer_in_func)(device_t *, usb_target_t, 363 usbhc_iface_transfer_in_callback_t, void *), 364 int (*transfer_out_func)(device_t *, usb_target_t, 365 usbhc_iface_transfer_out_callback_t, void *)) 366 { 367 switch (direction) { 368 case USB_DIRECTION_IN: 369 if (!transfer_in_func) { 370 ipc_answer_0(callid, ENOTSUP); 371 return; 372 } 373 break; 374 case USB_DIRECTION_OUT: 375 if (!transfer_out_func) { 376 ipc_answer_0(callid, ENOTSUP); 377 return; 378 } 379 break; 380 default: 381 assert(false && "unreachable code"); 382 break; 383 } 384 385 usb_target_t target = { 386 .address = IPC_GET_ARG1(*call), 387 .endpoint = IPC_GET_ARG2(*call) 388 }; 389 390 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 391 trans->caller = callid; 392 trans->buffer = NULL; 393 trans->size = 0; 394 395 int rc; 396 switch (direction) { 397 case USB_DIRECTION_IN: 398 rc = transfer_in_func(device, target, 399 callback_in, trans); 400 break; 401 case USB_DIRECTION_OUT: 402 rc = transfer_out_func(device, target, 403 callback_out, trans); 404 break; 405 default: 406 assert(false && "unreachable code"); 407 break; 408 } 409 410 if (rc != EOK) { 411 ipc_answer_0(callid, rc); 412 free(trans); 413 } 414 return; 415 } 416 417 418 void remote_usbhc_interrupt_out(device_t *device, void *iface, 419 ipc_callid_t callid, ipc_call_t *call) 420 { 421 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 422 assert(usb_iface != NULL); 423 424 return remote_usbhc_out_transfer(device, callid, call, 425 usb_iface->interrupt_out); 426 } 427 428 void remote_usbhc_interrupt_in(device_t *device, void *iface, 429 ipc_callid_t callid, ipc_call_t *call) 430 { 431 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 432 assert(usb_iface != NULL); 433 434 return remote_usbhc_in_transfer(device, callid, call, 435 usb_iface->interrupt_in); 436 } 437 438 void remote_usbhc_control_write_setup(device_t *device, void *iface, 439 ipc_callid_t callid, ipc_call_t *call) 440 { 441 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 442 assert(usb_iface != NULL); 443 444 return remote_usbhc_out_transfer(device, callid, call, 445 usb_iface->control_write_setup); 446 } 447 448 void remote_usbhc_control_write_data(device_t *device, void *iface, 449 ipc_callid_t callid, ipc_call_t *call) 450 { 451 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 452 assert(usb_iface != NULL); 453 454 return remote_usbhc_out_transfer(device, callid, call, 455 usb_iface->control_write_data); 456 } 457 458 void remote_usbhc_control_write_status(device_t *device, void *iface, 459 ipc_callid_t callid, ipc_call_t *call) 460 { 461 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 462 assert(usb_iface != NULL); 463 464 return remote_usbhc_status_transfer(device, callid, call, 465 USB_DIRECTION_IN, usb_iface->control_write_status, NULL); 466 } 467 468 void remote_usbhc_control_read_setup(device_t *device, void *iface, 469 ipc_callid_t callid, ipc_call_t *call) 470 { 471 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 472 assert(usb_iface != NULL); 473 474 return remote_usbhc_out_transfer(device, callid, call, 475 usb_iface->control_read_setup); 476 } 477 478 void remote_usbhc_control_read_data(device_t *device, void *iface, 479 ipc_callid_t callid, ipc_call_t *call) 480 { 481 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 482 assert(usb_iface != NULL); 483 484 return remote_usbhc_in_transfer(device, callid, call, 485 usb_iface->control_read_data); 486 } 487 488 void remote_usbhc_control_read_status(device_t *device, void *iface, 489 ipc_callid_t callid, ipc_call_t *call) 490 { 491 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 492 assert(usb_iface != NULL); 493 494 return remote_usbhc_status_transfer(device, callid, call, 495 USB_DIRECTION_OUT, NULL, usb_iface->control_read_status); 496 } 497 498 201 499 202 500 /** -
uspace/lib/drv/include/usbhc_iface.h
r56b962d r84439d7 92 92 */ 93 93 typedef enum { 94 /** Tell USB address assigned to device. 95 * Parameters: 96 * - devman handle id 97 * Answer: 98 * - EINVAL - unknown handle or handle not managed by this driver 99 * - ENOTSUP - operation not supported by HC (shall not happen) 100 * - arbitrary error code if returned by remote implementation 101 * - EOK - handle found, first parameter contains the USB address 102 */ 103 IPC_M_USBHC_GET_ADDRESS, 104 94 105 /** Asks for data buffer. 95 106 * See explanation at usb_iface_funcs_t. … … 100 111 101 112 113 /** Reserve usage of default address. 114 * This call informs the host controller that the caller will be 115 * using default USB address. It is duty of the HC driver to ensure 116 * that only single entity will have it reserved. 117 * The address is returned via IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS. 118 * The caller can start using the address after receiving EOK 119 * answer. 120 */ 121 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, 122 123 /** Release usage of default address. 124 * @see IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS 125 */ 126 IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS, 127 128 /** Asks for address assignment by host controller. 129 * Answer: 130 * - ELIMIT - host controller run out of address 131 * - EOK - address assigned 132 * Answer arguments: 133 * - assigned address 134 * 135 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS. 136 */ 137 IPC_M_USBHC_REQUEST_ADDRESS, 138 139 /** Bind USB address with devman handle. 140 * Parameters: 141 * - USB address 142 * - devman handle 143 * Answer: 144 * - EOK - address binded 145 * - ENOENT - address is not in use 146 */ 147 IPC_M_USBHC_BIND_ADDRESS, 148 149 /** Release address in use. 150 * Arguments: 151 * - address to be released 152 * Answer: 153 * - ENOENT - address not in use 154 * - EPERM - trying to release default USB address 155 */ 156 IPC_M_USBHC_RELEASE_ADDRESS, 157 158 102 159 /** Send interrupt data to device. 103 160 * See explanation at usb_iface_funcs_t (OUT transaction). … … 155 212 usb_transaction_outcome_t, size_t, void *); 156 213 214 215 /** Out transfer processing function prototype. */ 216 typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, 217 void *, size_t, 218 usbhc_iface_transfer_out_callback_t, void *); 219 220 /** Setup transfer processing function prototype. */ 221 typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t; 222 223 /** In transfer processing function prototype. */ 224 typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, 225 void *, size_t, 226 usbhc_iface_transfer_in_callback_t, void *); 227 157 228 /** USB devices communication interface. */ 158 229 typedef struct { 159 int (*interrupt_out)(device_t *, usb_target_t, 160 void *, size_t, 230 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 231 232 int (*reserve_default_address)(device_t *); 233 int (*release_default_address)(device_t *); 234 int (*request_address)(device_t *, usb_address_t *); 235 int (*bind_address)(device_t *, usb_address_t, devman_handle_t); 236 int (*release_address)(device_t *, usb_address_t); 237 238 usbhc_iface_transfer_out_t interrupt_out; 239 usbhc_iface_transfer_in_t interrupt_in; 240 241 usbhc_iface_transfer_setup_t control_write_setup; 242 usbhc_iface_transfer_out_t control_write_data; 243 int (*control_write_status)(device_t *, usb_target_t, 244 usbhc_iface_transfer_in_callback_t, void *); 245 246 usbhc_iface_transfer_setup_t control_read_setup; 247 usbhc_iface_transfer_in_t control_read_data; 248 int (*control_read_status)(device_t *, usb_target_t, 161 249 usbhc_iface_transfer_out_callback_t, void *); 162 int (*interrupt_in)(device_t *, usb_target_t,163 void *, size_t,164 usbhc_iface_transfer_in_callback_t, void *);165 250 } usbhc_iface_t; 166 251
Note:
See TracChangeset
for help on using the changeset viewer.
