1 #include <minix/config.h>
2 #include <minix/const.h>
5 #include <minix/safecopies.h>
6 #include <minix/sysutil.h>
12 static struct usb_urb
* pending_urbs
= NULL
;
13 static endpoint_t hcd_ep
;
15 static void _usb_urb_complete(struct usb_driver
*ud
, long urb_id
);
17 /*****************************************************************************
19 ****************************************************************************/
20 int usb_send_urb(struct usb_urb
* urb
)
34 gid
= cpf_grant_direct(hcd_ep
,(vir_bytes
) &urb
->dev_id
,
35 urb
->urb_size
- sizeof(void*),CPF_WRITE
|CPF_READ
);
38 printf("usb_send_urb: grant failed: "
39 "cpf_grant_direct(%d,%p,%d)\n", hcd_ep
, urb
, urb
->urb_size
);
46 msg
.m_type
= USB_RQ_SEND_URB
;
47 msg
.USB_GRANT_ID
= gid
;
48 msg
.USB_GRANT_SIZE
= urb
->urb_size
-sizeof(void*);
51 res
= sendrec(hcd_ep
, &msg
);
54 panic("usb_send_urb: could not talk to hcd: %d", res
);
57 if (msg
.m_type
!= USB_REPLY
) {
58 panic("usb_send_urb: got illegal response from hcd: %d", msg
.m_type
);
61 if (msg
.USB_RESULT
!= 0) {
62 panic("usb_send_urb: hcd could not enqueue URB: %d", msg
.USB_RESULT
);
65 /* everything ok, add urb to pending_urbs */
66 urb
->urb_id
= msg
.USB_URB_ID
;
67 urb
->next
= pending_urbs
;
72 /* (The HCD will send us a message when the URB is completed.) */
77 /*****************************************************************************
79 ****************************************************************************/
80 int usb_cancle_urb(struct usb_urb
* urb
)
86 panic("usb_send_urb: urb == NULL!");
89 if (urb
->urb_id
== USB_INVALID_URB_ID
) {
94 msg
.m_type
= USB_RQ_CANCEL_URB
;
95 msg
.USB_URB_ID
= urb
->urb_id
;
98 res
= sendrec(hcd_ep
, &msg
);
101 panic("usb_cancle_urb: could not talk to hcd: %d", res
);
104 if (msg
.m_type
!= USB_REPLY
) {
105 panic("usb_cancle_urb: got illegal response from hcd: %d", msg
.m_type
);
108 if (msg
.USB_RESULT
!= 0) {
109 panic("usb_cancle_urb: got illegal response from hcd: %d", msg
.m_type
);
112 res
= msg
.USB_RESULT
;
118 /*****************************************************************************
120 ****************************************************************************/
121 int usb_init(char *name
)
126 /* get the endpoint of the HCD */
127 res
= ds_retrieve_label_endpt("usbd", &hcd_ep
);
130 panic("usb_init: ds_retrieve_label_endpt failed for 'usb': %d", res
);
133 msg
.m_type
= USB_RQ_INIT
;
135 strncpy(msg
.USB_RB_INIT_NAME
, name
, M3_LONG_STRING
);
137 res
= sendrec(hcd_ep
, &msg
);
140 panic("usb_init: can't talk to USB: %d", res
);
143 if (msg
.m_type
!= USB_REPLY
) {
144 panic("usb_init: bad reply from USB: %d", msg
.m_type
);
147 if (msg
.USB_RESULT
!= 0 ) {
148 panic("usb_init: init failed: %d", msg
.USB_RESULT
);
154 /*****************************************************************************
155 * _usb_urb_complete *
156 ****************************************************************************/
157 static void _usb_urb_complete(struct usb_driver
*ud
, long urb_id
)
159 /* find the corresponding URB in the urb_pending list. */
160 struct usb_urb
* urb
= NULL
;
161 if (pending_urbs
!= NULL
) {
162 if (pending_urbs
->urb_id
== urb_id
) {
164 pending_urbs
= urb
->next
;
166 struct usb_urb
*u
= pending_urbs
;
168 if (u
->next
->urb_id
== urb_id
) {
170 u
->next
= u
->next
->next
;
179 /* Did we find a URB? */
182 cpf_revoke(urb
->gid
);
183 /* call completion handler */
187 ud
->urb_completion(urb
);
189 printf("WARN: _usb_urb_complete: did not find URB with ID %ld", urb_id
);
193 /*****************************************************************************
195 ****************************************************************************/
196 int usb_handle_msg(struct usb_driver
*ud
, message
*msg
)
199 * we expect kind of messages:
204 * NOTE: the hcd driver doesn't expect replies for these messages.
211 switch(msg
->m_type
) {
212 case USB_COMPLETE_URB
:
213 _usb_urb_complete(ud
, msg
->USB_URB_ID
);
215 case USB_ANNOUCE_DEV
:
216 ud
->connect_device(msg
->USB_DEV_ID
, msg
->USB_INTERFACES
);
218 case USB_WITHDRAW_DEV
:
219 ud
->disconnect_device(msg
->USB_DEV_ID
);
222 panic("usb_handle_msg: bogus message from USB");