//----------------------------------------------------------------- // usb_cdc_process_request: //----------------------------------------------------------------- void usb_cdc_process_request(unsigned char req, unsigned short wValue, unsigned short WIndex, unsigned char *data, unsigned short wLength) { switch ( req ) { case CDC_SEND_ENCAPSULATED_COMMAND: log_printf(USBLOG_CDC_INFO, "CDC: Send encap\n"); cdc_send_encapsulated_command(); break; case CDC_GET_ENCAPSULATED_RESPONSE: log_printf(USBLOG_CDC_INFO, "CDC: Get encap\n"); cdc_get_encapsulated_response(wLength); break; case CDC_SET_LINE_CODING: log_printf(USBLOG_CDC_INFO, "CDC: Set line coding\n"); cdc_set_line_coding(data); break; case CDC_GET_LINE_CODING: log_printf(USBLOG_CDC_INFO, "CDC: Get line coding\n"); cdc_get_line_coding(wLength); break; case CDC_SET_CONTROL_LINE_STATE: log_printf(USBLOG_CDC_INFO, "CDC: Set line state\n"); cdc_set_control_line_state(); break; case CDC_SEND_BREAK: log_printf(USBLOG_CDC_INFO, "CDC: Send break\n"); cdc_send_break(); break; default: log_printf(USBLOG_CDC_INFO, "CDC: Unknown command\n"); usbhw_control_endpoint_stall(); break; } }
/** * Receive control packet * * @v acm USB RNDIS device * @ret rc Return status code */ static int acm_control_receive ( struct acm_device *acm ) { struct rndis_device *rndis = acm->rndis; struct usb_device *usb = acm->usb; struct io_buffer *iobuf; struct rndis_header *header; size_t mtu = ACM_RESPONSE_MTU; size_t len; int rc; /* Allocate I/O buffer */ iobuf = alloc_iob ( mtu ); if ( ! iobuf ) { rc = -ENOMEM; goto err_alloc; } /* Get encapsulated response */ if ( ( rc = cdc_get_encapsulated_response ( usb, acm->usbnet.comms, iobuf->data, mtu ) ) != 0 ){ DBGC ( acm, "ACM %p could not get encapsulated response: %s\n", acm, strerror ( rc ) ); goto err_get_response; } /* Fix up buffer length */ header = iobuf->data; len = le32_to_cpu ( header->len ); if ( len > mtu ) { DBGC ( acm, "ACM %p overlength encapsulated response\n", acm ); DBGC_HDA ( acm, 0, iobuf->data, mtu ); rc = -EPROTO; goto err_len; } iob_put ( iobuf, len ); /* Hand off to RNDIS */ rndis_rx ( rndis, iob_disown ( iobuf ) ); return 0; err_len: err_get_response: free_iob ( iobuf ); err_alloc: return rc; }