0,0 → 1,115 |
|
struc URB |
{ |
.fd dd ? |
.bk dd ? |
.dev dd ? ; pointer to associated device |
.pipe dd ? ; pipe information |
.status dd ? ; non-ISO status |
.transfer_flags dd ? ; URB_SHORT_NOT_OK | ... |
.transfer_buffer dd ? ; associated data buffer |
.transfer_dma dd ? ; dma addr for transfer_buffer |
.transfer_buffer_length dd ? ; data buffer length |
.actual_length dd ? ; actual transfer length |
.setup_packet dd ? ; setup packet (control only) |
.setup_dma dd ? ; dma addr for setup_packet |
.start_frame dd ? ; start frame (ISO) |
.number_of_packets dd ? ; number of ISO packets |
.interval dd ? ; transfer interval |
|
.error_count dd ? ; number of ISO errors |
.context dd ? ; context for completion |
.complete dd ? ; (in) completion routine |
.iso_frame_desc: |
} |
|
virtual at 0 |
URB URB |
end virtual |
|
|
struc REQ ;usb request |
{ |
.request_type db ? |
.request db ? |
.value dw ? |
.index dw ? |
.length dw ? |
} |
|
virtual at 0 |
REQ REQ |
end virtual |
|
align 4 |
proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\ |
requesttype:dword, value:dword, index:dword,\ |
data:dword, size:dword, timeout:dword |
|
locals |
req REQ |
endl |
|
lea eax, [req] |
mov ecx, [request] |
mov ebx, [requesttupe] |
mov edx, [value] |
mov esi, [index] |
mov edi, [size] |
|
mov [eax+REQ.request_type], bl |
mov [eax+REQ.request], cl |
mov [eax+REQ.value], dx |
mov [eax+REQ.index], si |
mov [eax+REQ.length], di |
|
stdcall usb_internal_control_msg, [dev], [pipe],\ |
eax, [data], [size], [timeout] |
|
ret |
endp |
|
|
; returns status (negative) or length (positive) |
static int usb_internal_control_msg(struct usb_device *usb_dev, |
unsigned int pipe, |
struct usb_ctrlrequest *cmd, |
void *data, int len, int timeout) |
{ |
struct urb *urb; |
int retv; |
int length; |
|
urb = usb_alloc_urb(0, GFP_NOIO); |
if (!urb) |
return -ENOMEM; |
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, |
len, usb_api_blocking_completion, NULL); |
|
retv = usb_start_wait_urb(urb, timeout, &length); |
if (retv < 0) |
return retv; |
else |
return length; |
} |
|
|
void usb_fill_control_urb (struct urb *urb, |
struct usb_device *dev, |
unsigned int pipe, |
unsigned char *setup_packet, |
void *transfer_buffer, |
int buffer_length, |
usb_complete_t complete_fn, |
void *context) |
{ |
|
urb->dev = dev; |
urb->pipe = pipe; |
urb->setup_packet = setup_packet; |
urb->transfer_buffer = transfer_buffer; |
urb->transfer_buffer_length = buffer_length; |
urb->complete = complete_fn; |
urb->context = context; |
} |
|