Changeset 78f01ff9 in mainline
- Timestamp:
- 2010-11-28T22:25:01Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4570779, c39544a
- Parents:
- 36bcf84f (diff), 1f43c8f (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
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/usbkbd.ma
r36bcf84f r78f01ff9 1 1 10 usb&class=hid 2 10 usb&hid -
uspace/lib/drv/generic/remote_usbhc.c
r36bcf84f r78f01ff9 159 159 } 160 160 161 void remote_usbhc_interrupt_out(device_t *device, void *iface, 162 ipc_callid_t callid, ipc_call_t *call) 163 { 164 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 161 /** Process an outgoing transfer (both OUT and SETUP). 162 * 163 * @param device Target device. 164 * @param callid Initiating caller. 165 * @param call Initiating call. 166 * @param transfer_func Transfer function (might be NULL). 167 */ 168 static void remote_usbhc_out_transfer(device_t *device, 169 ipc_callid_t callid, ipc_call_t *call, 170 usbhc_iface_transfer_out_t transfer_func) 171 { 172 if (!transfer_func) { 173 ipc_answer_0(callid, ENOTSUP); 174 return; 175 } 165 176 166 177 size_t expected_len = IPC_GET_ARG3(*call); … … 183 194 } 184 195 185 if (!usb_iface->interrupt_out) {186 ipc_answer_0(callid, ENOTSUP);187 return;188 }189 190 196 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 191 197 trans->caller = callid; 192 trans->buffer = NULL;193 trans->size = 0;194 195 int rc = usb_iface->interrupt_out(device, target, buffer, len,198 trans->buffer = buffer; 199 trans->size = len; 200 201 int rc = transfer_func(device, target, buffer, len, 196 202 callback_out, trans); 197 203 198 204 if (rc != EOK) { 199 205 ipc_answer_0(callid, rc); 206 if (buffer != NULL) { 207 free(buffer); 208 } 200 209 free(trans); 201 210 } 202 211 } 203 212 204 void remote_usbhc_interrupt_in(device_t *device, void *iface, 205 ipc_callid_t callid, ipc_call_t *call) 206 { 207 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 213 /** Process an incoming transfer. 214 * 215 * @param device Target device. 216 * @param callid Initiating caller. 217 * @param call Initiating call. 218 * @param transfer_func Transfer function (might be NULL). 219 */ 220 static void remote_usbhc_in_transfer(device_t *device, 221 ipc_callid_t callid, ipc_call_t *call, 222 usbhc_iface_transfer_in_t transfer_func) 223 { 224 if (!transfer_func) { 225 ipc_answer_0(callid, ENOTSUP); 226 return; 227 } 208 228 209 229 size_t len = IPC_GET_ARG3(*call); … … 213 233 }; 214 234 215 if (!usb_iface->interrupt_in) {216 ipc_answer_0(callid, ENOTSUP);217 return;218 }219 220 235 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 221 236 trans->caller = callid; … … 223 238 trans->size = len; 224 239 225 int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,240 int rc = transfer_func(device, target, trans->buffer, len, 226 241 callback_in, trans); 227 242 … … 233 248 } 234 249 235 void remote_usbhc_control_write_setup(device_t *device, void *iface, 236 ipc_callid_t callid, ipc_call_t *call) 237 { 238 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 239 240 size_t expected_len = IPC_GET_ARG3(*call); 250 /** Process status part of control transfer. 251 * 252 * @param device Target device. 253 * @param callid Initiating caller. 254 * @param call Initiating call. 255 * @param direction Transfer direction (read ~ in, write ~ out). 256 * @param transfer_in_func Transfer function for control read (might be NULL). 257 * @param transfer_out_func Transfer function for control write (might be NULL). 258 */ 259 static void remote_usbhc_status_transfer(device_t *device, 260 ipc_callid_t callid, ipc_call_t *call, 261 usb_direction_t direction, 262 int (*transfer_in_func)(device_t *, usb_target_t, 263 usbhc_iface_transfer_in_callback_t, void *), 264 int (*transfer_out_func)(device_t *, usb_target_t, 265 usbhc_iface_transfer_out_callback_t, void *)) 266 { 267 switch (direction) { 268 case USB_DIRECTION_IN: 269 if (!transfer_in_func) { 270 ipc_answer_0(callid, ENOTSUP); 271 return; 272 } 273 break; 274 case USB_DIRECTION_OUT: 275 if (!transfer_out_func) { 276 ipc_answer_0(callid, ENOTSUP); 277 return; 278 } 279 break; 280 default: 281 assert(false && "unreachable code"); 282 break; 283 } 284 241 285 usb_target_t target = { 242 286 .address = IPC_GET_ARG1(*call), … … 244 288 }; 245 289 246 size_t len = 0;247 void *buffer = NULL;248 if (expected_len > 0) {249 int rc = async_data_write_accept(&buffer, false,250 1, USB_MAX_PAYLOAD_SIZE,251 0, &len);252 253 if (rc != EOK) {254 ipc_answer_0(callid, rc);255 return;256 }257 }258 259 if (!usb_iface->control_write_setup) {260 ipc_answer_0(callid, ENOTSUP);261 return;262 }263 264 290 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 265 291 trans->caller = callid; … … 267 293 trans->size = 0; 268 294 269 int rc = usb_iface->control_write_setup(device, target, buffer, len, 270 callback_out, trans); 295 int rc; 296 switch (direction) { 297 case USB_DIRECTION_IN: 298 rc = transfer_in_func(device, target, 299 callback_in, trans); 300 break; 301 case USB_DIRECTION_OUT: 302 rc = transfer_out_func(device, target, 303 callback_out, trans); 304 break; 305 default: 306 assert(false && "unreachable code"); 307 break; 308 } 271 309 272 310 if (rc != EOK) { … … 274 312 free(trans); 275 313 } 314 return; 315 } 316 317 318 void remote_usbhc_interrupt_out(device_t *device, void *iface, 319 ipc_callid_t callid, ipc_call_t *call) 320 { 321 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 322 assert(usb_iface != NULL); 323 324 return remote_usbhc_out_transfer(device, callid, call, 325 usb_iface->interrupt_out); 326 } 327 328 void remote_usbhc_interrupt_in(device_t *device, void *iface, 329 ipc_callid_t callid, ipc_call_t *call) 330 { 331 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 332 assert(usb_iface != NULL); 333 334 return remote_usbhc_in_transfer(device, callid, call, 335 usb_iface->interrupt_in); 336 } 337 338 void remote_usbhc_control_write_setup(device_t *device, void *iface, 339 ipc_callid_t callid, ipc_call_t *call) 340 { 341 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 342 assert(usb_iface != NULL); 343 344 return remote_usbhc_out_transfer(device, callid, call, 345 usb_iface->control_write_setup); 276 346 } 277 347 278 348 void remote_usbhc_control_write_data(device_t *device, void *iface, 279 ipc_callid_t callid, ipc_call_t *call) 280 { 281 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 282 283 size_t expected_len = IPC_GET_ARG3(*call); 284 usb_target_t target = { 285 .address = IPC_GET_ARG1(*call), 286 .endpoint = IPC_GET_ARG2(*call) 287 }; 288 289 size_t len = 0; 290 void *buffer = NULL; 291 if (expected_len > 0) { 292 int rc = async_data_write_accept(&buffer, false, 293 1, USB_MAX_PAYLOAD_SIZE, 294 0, &len); 295 296 if (rc != EOK) { 297 ipc_answer_0(callid, rc); 298 return; 299 } 300 } 301 302 if (!usb_iface->control_write_data) { 303 ipc_answer_0(callid, ENOTSUP); 304 return; 305 } 306 307 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 308 trans->caller = callid; 309 trans->buffer = NULL; 310 trans->size = 0; 311 312 int rc = usb_iface->control_write_data(device, target, buffer, len, 313 callback_out, trans); 314 315 if (rc != EOK) { 316 ipc_answer_0(callid, rc); 317 free(trans); 318 } 349 ipc_callid_t callid, ipc_call_t *call) 350 { 351 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 352 assert(usb_iface != NULL); 353 354 return remote_usbhc_out_transfer(device, callid, call, 355 usb_iface->control_write_data); 319 356 } 320 357 321 358 void remote_usbhc_control_write_status(device_t *device, void *iface, 322 ipc_callid_t callid, ipc_call_t *call) 323 { 324 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 325 326 usb_target_t target = { 327 .address = IPC_GET_ARG1(*call), 328 .endpoint = IPC_GET_ARG2(*call) 329 }; 330 331 if (!usb_iface->control_write_status) { 332 ipc_answer_0(callid, ENOTSUP); 333 return; 334 } 335 336 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 337 trans->caller = callid; 338 trans->buffer = NULL; 339 trans->size = 0; 340 341 int rc = usb_iface->control_write_status(device, target, 342 callback_in, trans); 343 344 if (rc != EOK) { 345 ipc_answer_0(callid, rc); 346 free(trans); 347 } 359 ipc_callid_t callid, ipc_call_t *call) 360 { 361 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 362 assert(usb_iface != NULL); 363 364 return remote_usbhc_status_transfer(device, callid, call, 365 USB_DIRECTION_IN, usb_iface->control_write_status, NULL); 348 366 } 349 367 350 368 void remote_usbhc_control_read_setup(device_t *device, void *iface, 351 ipc_callid_t callid, ipc_call_t *call) 352 { 353 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 354 355 size_t expected_len = IPC_GET_ARG3(*call); 356 usb_target_t target = { 357 .address = IPC_GET_ARG1(*call), 358 .endpoint = IPC_GET_ARG2(*call) 359 }; 360 361 size_t len = 0; 362 void *buffer = NULL; 363 if (expected_len > 0) { 364 int rc = async_data_write_accept(&buffer, false, 365 1, USB_MAX_PAYLOAD_SIZE, 366 0, &len); 367 368 if (rc != EOK) { 369 ipc_answer_0(callid, rc); 370 return; 371 } 372 } 373 374 if (!usb_iface->control_read_setup) { 375 ipc_answer_0(callid, ENOTSUP); 376 return; 377 } 378 379 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 380 trans->caller = callid; 381 trans->buffer = NULL; 382 trans->size = 0; 383 384 int rc = usb_iface->control_read_setup(device, target, buffer, len, 385 callback_out, trans); 386 387 if (rc != EOK) { 388 ipc_answer_0(callid, rc); 389 free(trans); 390 } 369 ipc_callid_t callid, ipc_call_t *call) 370 { 371 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 372 assert(usb_iface != NULL); 373 374 return remote_usbhc_out_transfer(device, callid, call, 375 usb_iface->control_read_setup); 391 376 } 392 377 … … 395 380 { 396 381 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 397 398 size_t len = IPC_GET_ARG3(*call); 399 usb_target_t target = { 400 .address = IPC_GET_ARG1(*call), 401 .endpoint = IPC_GET_ARG2(*call) 402 }; 403 404 if (!usb_iface->control_read_data) { 405 ipc_answer_0(callid, ENOTSUP); 406 return; 407 } 408 409 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 410 trans->caller = callid; 411 trans->buffer = malloc(len); 412 trans->size = len; 413 414 int rc = usb_iface->control_read_data(device, target, trans->buffer, len, 415 callback_in, trans); 416 417 if (rc != EOK) { 418 ipc_answer_0(callid, rc); 419 free(trans->buffer); 420 free(trans); 421 } 382 assert(usb_iface != NULL); 383 384 return remote_usbhc_in_transfer(device, callid, call, 385 usb_iface->control_read_data); 422 386 } 423 387 … … 426 390 { 427 391 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 428 429 usb_target_t target = { 430 .address = IPC_GET_ARG1(*call), 431 .endpoint = IPC_GET_ARG2(*call) 432 }; 433 434 if (!usb_iface->control_read_status) { 435 ipc_answer_0(callid, ENOTSUP); 436 return; 437 } 438 439 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 440 trans->caller = callid; 441 trans->buffer = NULL; 442 trans->size = 0; 443 444 int rc = usb_iface->control_read_status(device, target, 445 callback_out, trans); 446 447 if (rc != EOK) { 448 ipc_answer_0(callid, rc); 449 free(trans); 450 } 392 assert(usb_iface != NULL); 393 394 return remote_usbhc_status_transfer(device, callid, call, 395 USB_DIRECTION_OUT, NULL, usb_iface->control_read_status); 451 396 } 452 397 -
uspace/lib/drv/include/usbhc_iface.h
r36bcf84f r78f01ff9 166 166 usb_transaction_outcome_t, size_t, void *); 167 167 168 169 /** Out transfer processing function prototype. */ 170 typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, 171 void *, size_t, 172 usbhc_iface_transfer_out_callback_t, void *); 173 174 /** Setup transfer processing function prototype. */ 175 typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t; 176 177 /** In transfer processing function prototype. */ 178 typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, 179 void *, size_t, 180 usbhc_iface_transfer_in_callback_t, void *); 181 168 182 /** USB devices communication interface. */ 169 183 typedef struct { 170 184 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 171 185 172 int (*interrupt_out)(device_t *, usb_target_t, 173 void *, size_t, 174 usbhc_iface_transfer_out_callback_t, void *); 175 int (*interrupt_in)(device_t *, usb_target_t, 176 void *, size_t, 177 usbhc_iface_transfer_in_callback_t, void *); 178 179 int (*control_write_setup)(device_t *, usb_target_t, 180 void *, size_t, 181 usbhc_iface_transfer_out_callback_t, void *); 182 int (*control_write_data)(device_t *, usb_target_t, 183 void *, size_t, 184 usbhc_iface_transfer_out_callback_t, void *); 186 usbhc_iface_transfer_out_t interrupt_out; 187 usbhc_iface_transfer_in_t interrupt_in; 188 189 usbhc_iface_transfer_setup_t control_write_setup; 190 usbhc_iface_transfer_out_t control_write_data; 185 191 int (*control_write_status)(device_t *, usb_target_t, 186 192 usbhc_iface_transfer_in_callback_t, void *); 187 193 188 int (*control_read_setup)(device_t *, usb_target_t, 189 void *, size_t, 190 usbhc_iface_transfer_out_callback_t, void *); 191 int (*control_read_data)(device_t *, usb_target_t, 192 void *, size_t, 193 usbhc_iface_transfer_in_callback_t, void *); 194 usbhc_iface_transfer_setup_t control_read_setup; 195 usbhc_iface_transfer_in_t control_read_data; 194 196 int (*control_read_status)(device_t *, usb_target_t, 195 197 usbhc_iface_transfer_out_callback_t, void *); -
uspace/lib/usb/include/usb/hcdhubd.h
r36bcf84f r78f01ff9 37 37 38 38 #include <adt/list.h> 39 #include <bool.h> 39 40 #include <driver.h> 40 41 #include <usb/usb.h> … … 175 176 int usb_hc_async_wait_for(usb_handle_t); 176 177 177 int usb_hc_add_child_device(device_t *, const char *, const char * );178 int usb_hc_add_child_device(device_t *, const char *, const char *, bool); 178 179 179 180 #endif -
uspace/lib/usb/src/hcdhubd.c
r36bcf84f r78f01ff9 40 40 #include <bool.h> 41 41 #include <errno.h> 42 #include <str_error.h> 42 43 #include <usb/classes/hub.h> 43 44 … … 112 113 } 113 114 114 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id );115 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true); 115 116 if (rc != EOK) { 116 117 free(id); … … 150 151 match_id->id = child_info->match_id; 151 152 match_id->score = 10; 152 printf("adding child device with match \"%s\"\n", match_id->id);153 153 add_match_id(&child->match_ids, match_id); 154 154 155 printf("%s: adding child device `%s' with match \"%s\"\n", 156 hc_driver->name, child->name, match_id->id); 155 157 rc = child_device_register(child, child_info->parent); 158 printf("%s: child device `%s' registration: %s\n", 159 hc_driver->name, child->name, str_error(rc)); 160 156 161 if (rc != EOK) { 157 162 goto failure; … … 173 178 leave: 174 179 free(arg); 175 return rc;180 return EOK; 176 181 } 177 182 … … 180 185 * driven by the same task, the child adding is done in separate fibril. 181 186 * Not optimal, but it works. 187 * Update: not under all circumstances the new fibril is successful either. 188 * Thus the last parameter to let the caller choose. 182 189 * 183 190 * @param parent Parent device. 184 191 * @param name Device name. 185 192 * @param match_id Match id. 193 * @param create_fibril Whether to run the addition in new fibril. 186 194 * @return Error code. 187 195 */ 188 196 int usb_hc_add_child_device(device_t *parent, const char *name, 189 const char *match_id) 190 { 197 const char *match_id, bool create_fibril) 198 { 199 printf("%s: about to add child device `%s' (%s)\n", hc_driver->name, 200 name, match_id); 201 191 202 struct child_device_info *child_info 192 203 = malloc(sizeof(struct child_device_info)); … … 196 207 child_info->match_id = match_id; 197 208 198 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 199 if (!fibril) { 200 return ENOMEM; 201 } 202 fibril_add_ready(fibril); 209 if (create_fibril) { 210 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 211 if (!fibril) { 212 return ENOMEM; 213 } 214 fibril_add_ready(fibril); 215 } else { 216 fibril_add_child_device(child_info); 217 } 203 218 204 219 return EOK; -
uspace/lib/usb/src/hcdrv.c
r36bcf84f r78f01ff9 54 54 }; 55 55 56 int usb_add_hc_device(device_t *dev) 57 { 56 static usb_hc_device_t *usb_hc_device_create(device_t *dev) { 58 57 usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t)); 58 59 59 list_initialize(&hc_dev->link); 60 list_initialize(&hc_dev->hubs); 61 list_initialize(&hc_dev->attached_devices); 60 62 hc_dev->transfer_ops = NULL; 61 63 … … 63 65 dev->ops = &usb_device_ops; 64 66 hc_dev->generic->driver_data = hc_dev; 67 68 return hc_dev; 69 } 70 71 int usb_add_hc_device(device_t *dev) 72 { 73 usb_hc_device_t *hc_dev = usb_hc_device_create(dev); 65 74 66 75 int rc = hc_driver->add_hc(hc_dev); … … 78 87 list_append(&hc_dev->link, &hc_list); 79 88 80 //add keyboard81 /// @TODO this is not correct code82 83 89 /* 84 * Announce presence of child device. 90 * FIXME: the following is a workaround to force loading of USB 91 * keyboard driver. 92 * Will be removed as soon as the hub driver is completed and 93 * can detect connected devices. 85 94 */ 86 device_t *kbd = NULL; 87 match_id_t *match_id = NULL; 88 89 kbd = create_device(); 90 if (kbd == NULL) { 91 printf("ERROR: enomem\n"); 92 } 93 kbd->name = USB_KBD_DEVICE_NAME; 94 95 match_id = create_match_id(); 96 if (match_id == NULL) { 97 printf("ERROR: enomem\n"); 95 printf("%s: trying to add USB HID child device...\n", hc_driver->name); 96 rc = usb_hc_add_child_device(dev, USB_KBD_DEVICE_NAME, "usb&hid", false); 97 if (rc != EOK) { 98 printf("%s: adding USB HID child failed...\n", hc_driver->name); 98 99 } 99 100 100 char *id;101 rc = asprintf(&id, USB_KBD_DEVICE_NAME);102 if (rc <= 0) {103 printf("ERROR: enomem\n");104 return rc;105 }106 107 match_id->id = id;108 match_id->score = 30;109 110 add_match_id(&kbd->match_ids, match_id);111 112 rc = child_device_register(kbd, dev);113 if (rc != EOK) {114 printf("ERROR: cannot register kbd\n");115 return rc;116 }117 118 printf("%s: registered root hub\n", dev->name);119 101 return EOK; 120 102 }
Note:
See TracChangeset
for help on using the changeset viewer.