Changeset fb1dca09 in mainline
- Timestamp:
- 2010-11-28T20:58:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ba7f671
- Parents:
- 710f518
- Location:
- uspace/lib/drv
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
r710f518 rfb1dca09 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
r710f518 rfb1dca09 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 *);
Note:
See TracChangeset
for help on using the changeset viewer.