2
* Purpose: USB device interface (udi.h) routines for Solaris
6
* This file is part of Open Sound System.
8
* Copyright (C) 4Front Technologies 1996-2008.
10
* This this source file is released under GPL v2 license (no other versions).
11
* See the COPYING file included in the main directory of this source
12
* distribution for the license terms and conditions.
16
#include "oss_config.h"
19
#define USBDRV_MAJOR_VER 2
20
#define USBDRV_MINOR_VER 0
21
#include <sys/usb/usba.h>
22
#include <sys/strsubr.h>
25
int udi_usb_trace = 0;
27
#define MAX_DEVICE_SLOTS 20
32
usb_client_dev_data_t *dev_data;
35
const struct usb_device_id *id;
36
const udi_usb_devinfo *udi_usb_dev;
41
struct usb_interface *iface;
44
void (*client_disconnect) (void *devc);
50
udi_attach_usbdriver (oss_device_t * osdev, const udi_usb_devinfo * devlist,
51
udi_usb_driver * driver)
53
int err, i, nalt, vendor, product, busaddr;
55
dev_info_t *dip = osdev->dip;
58
//usb_alt_if_data_t *altif_data;
59
usb_client_dev_data_t *dev_data;
63
cmn_err(CE_WARN, "dip==NULL\n");
67
name = ddi_get_name (osdev->dip);
69
if (strcmp (name, "oss_usb") == 0)
71
oss_register_device (osdev, "USB audio/MIDI device");
76
* Select the default configuration
78
if ((err = usb_set_cfg (osdev->dip, USB_DEV_DEFAULT_CONFIG_INDEX,
79
USB_FLAGS_SLEEP, NULL, NULL)) == USB_SUCCESS)
81
cmn_err (CE_CONT, "usb_set_cfg returned %d\n", err);
84
busaddr = ddi_prop_get_int (DDI_DEV_T_ANY, osdev->dip,
85
DDI_PROP_NOTPROM, "assigned-address", 1234);
86
if ((usbdev = KERNEL_MALLOC (sizeof (*usbdev))) == NULL)
88
cmn_err (CE_WARN, "udi_attach_usbdriver: Out of memory\n");
92
memset (usbdev, 0, sizeof (*usbdev));
93
osdev->usbdev = usbdev;
94
usbdev->osdev = osdev;
96
if ((err = usb_client_attach (dip, USBDRV_VERSION, 0)) != USB_SUCCESS)
98
cmn_err (CE_WARN, "usb_client_attach failed, err=%d\n", err);
104
usb_get_dev_data (osdev->dip, &usbdev->dev_data, USB_PARSE_LVL_CFG,
107
cmn_err (CE_WARN, "usb_get_dev_data failed, err=%d\n", err);
108
KERNEL_FREE (usbdev);
111
dev_data = usbdev->dev_data;
113
osdev->iblock_cookie = dev_data->dev_iblock_cookie;
115
sprintf (usbdev->devpath, "usb%x,%x@port%d", udi_usbdev_get_vendor (usbdev),
116
udi_usbdev_get_product (usbdev), busaddr);
117
oss_register_device (osdev, "USB audio/MIDI device");
118
sprintf (osdev->nick, "usb%x_%x_%d", udi_usbdev_get_vendor (usbdev),
119
udi_usbdev_get_product (usbdev), busaddr);
122
if (udi_usb_trace > 5)
123
usb_print_descr_tree (osdev->dip, dev_data);
127
if (nalt >= dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
130
//altif_data = &dev_data->dev_curr_cfg->
131
// cfg_if[dev_data->dev_curr_if].if_alt[nalt];
133
usbdev->name = usbdev->dev_data->dev_product;
134
vendor = udi_usbdev_get_vendor (usbdev);
135
product = udi_usbdev_get_product (usbdev);
137
/* inum = usbdev->dev_data->dev_curr_if; */
138
osid = (vendor << 16) | product;
139
osdev->osid = (void *) osid;
141
sprintf (osdev->handle, "usb%x,%x.%d:%d", vendor, product,
142
dev_data->dev_curr_if, osdev->instance);
144
for (i = 0; devlist[i].vendor != -1; i++)
145
if (devlist[i].vendor == vendor && devlist[i].product == product)
147
usbdev->name = devlist[i].name;
148
usbdev->udi_usb_dev = &devlist[i];
149
oss_register_device (osdev, usbdev->name);
153
if ((usbdev->client_devc = driver->attach (usbdev, osdev)) == NULL)
155
cmn_err (CE_WARN, "Client attach failed, err=%d\n", err);
156
udi_unload_usbdriver (osdev);
160
usbdev->client_disconnect = driver->disconnect;
169
static struct errmsg_
176
USB_FAILURE, "USB_FAILURE"},
178
USB_NO_RESOURCES, "USB_NO_RESOURCES"},
180
USB_NO_BANDWIDTH, "USB_NO_BANDWIDTH"},
182
USB_NOT_SUPPORTED, "USB_NOT_SUPPORTED"},
184
USB_PIPE_ERROR, "USB_PIPE_ERROR"},
186
USB_INVALID_PIPE, "USB_INVALID_PIPE"},
188
USB_NO_FRAME_NUMBER, "USB_NO_FRAME_NUMBER"},
190
USB_INVALID_START_FRAME, "USB_INVALID_START_FRAME"},
192
USB_HC_HARDWARE_ERROR, "USB_HC_HARDWARE_ERROR"},
194
USB_INVALID_REQUEST, "USB_INVALID_REQUEST"},
196
USB_INVALID_CONTEXT, "USB_INVALID_CONTEXT"},
198
USB_INVALID_VERSION, "USB_INVALID_VERSION"},
200
USB_INVALID_ARGS, "USB_INVALID_ARGS"},
202
USB_INVALID_PERM, "USB_INVALID_PERM"},
204
USB_BUSY, "USB_BUSY"},
212
for (i = 0; errs[i].err != 0; i++)
213
if (errs[i].err == err)
218
sprintf (msg, "Err %d", err);
226
static struct errmsg_
233
USB_CB_STALL_CLEARED, "USB_CB_STALL_CLEARED"},
235
USB_CB_FUNCTIONAL_STALL, "USB_CB_FUNCTIONAL_STALL"},
237
USB_CB_PROTOCOL_STALL, "USB_CB_PROTOCOL_STALL"},
239
USB_CB_RESET_PIPE, "USB_CB_RESET_PIPE"},
241
USB_CB_ASYNC_REQ_FAILED, "USB_CB_ASYNC_REQ_FAILED"},
243
USB_CB_NO_RESOURCES, "USB_CB_NO_RESOURCES"},
245
USB_CB_SUBMIT_FAILED, "USB_CB_SUBMIT_FAILED"},
247
USB_CB_INTR_CONTEXT, "USB_CB_INTR_CONTEXT"},
249
USB_FAILURE, "USB_FAILURE"},
251
USB_NO_RESOURCES, "USB_NO_RESOURCES"},
253
USB_NO_BANDWIDTH, "USB_NO_BANDWIDTH"},
255
USB_NOT_SUPPORTED, "USB_NOT_SUPPORTED"},
257
USB_PIPE_ERROR, "USB_PIPE_ERROR"},
259
USB_INVALID_PIPE, "USB_INVALID_PIPE"},
261
USB_NO_FRAME_NUMBER, "USB_NO_FRAME_NUMBER"},
263
USB_INVALID_START_FRAME, "USB_INVALID_START_FRAME"},
265
USB_HC_HARDWARE_ERROR, "USB_HC_HARDWARE_ERROR"},
267
USB_INVALID_REQUEST, "USB_INVALID_REQUEST"},
269
USB_INVALID_CONTEXT, "USB_INVALID_CONTEXT"},
271
USB_INVALID_VERSION, "USB_INVALID_VERSION"},
273
USB_INVALID_ARGS, "USB_INVALID_ARGS"},
275
USB_INVALID_PERM, "USB_INVALID_PERM"},
277
USB_BUSY, "USB_BUSY"},
286
return "USB_CB_NO_INFO";
288
for (i = 0; errs[i].err != 0; i++)
290
if (errs[i].err == err)
296
sprintf (msg, "CB Err %d", err);
304
static struct errmsg_
311
USB_CR_CRC, "USB_CR_CRC"},
313
USB_CR_BITSTUFFING, "USB_CR_BITSTUFFING"},
315
USB_CR_DATA_TOGGLE_MM, "USB_CR_DATA_TOGGLE_MM"},
317
USB_CR_STALL, "USB_CR_STALL"},
319
USB_CR_DEV_NOT_RESP, "USB_CR_DEV_NOT_RESP"},
321
USB_CR_PID_CHECKFAILURE, "USB_CR_PID_CHECKFAILURE"},
323
USB_CR_UNEXP_PID, "USB_CR_UNEXP_PID"},
325
USB_CR_DATA_OVERRUN, "USB_CR_DATA_OVERRUN"},
327
USB_CR_DATA_UNDERRUN, "USB_CR_DATA_UNDERRUN"},
329
USB_CR_BUFFER_OVERRUN, "USB_CR_BUFFER_OVERRUN"},
331
USB_CR_BUFFER_UNDERRUN, "USB_CR_BUFFER_UNDERRUN"},
333
USB_CR_TIMEOUT, "USB_CR_TIMEOUT"},
335
USB_CR_NOT_ACCESSED, "USB_CR_NOT_ACCESSED"},
337
USB_CR_NO_RESOURCES, "USB_CR_NO_RESOURCES"},
339
USB_CR_UNSPECIFIED_ERR, "USB_CR_UNSPECIFIED_ERR"},
341
USB_CR_STOPPED_POLLING, "USB_CR_STOPPED_POLLING"},
343
USB_CR_PIPE_CLOSING, "USB_CR_PIPE_CLOSING"},
345
USB_CR_PIPE_RESET, "USB_CR_PIPE_RESET"},
347
USB_CR_NOT_SUPPORTED, "USB_CR_NOT_SUPPORTED"},
349
USB_CR_FLUSHED, "USB_CR_FLUSHED"},
351
USB_CR_HC_HARDWARE_ERR, "USB_CR_HC_HARDWARE_ERR"},
362
for (i = 0; errs[i].err != 0; i++)
364
if (errs[i].err == err)
370
sprintf (msg, "CR Err %d", err);
375
udi_unload_usbdriver (oss_device_t * osdev)
377
udi_usb_devc *usbdev = osdev->usbdev;
382
if (usbdev->client_disconnect != NULL)
383
usbdev->client_disconnect (usbdev->client_devc);
384
usb_client_detach (osdev->dip, usbdev->dev_data);
386
KERNEL_FREE (usbdev);
387
osdev->usbdev = NULL;
391
* Device access routines
395
udi_usbdev_get_class (udi_usb_devc * usbdev)
397
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
399
return devc->dev_data->dev_curr_cfg->cfg_if[devc->dev_data->dev_curr_if].
400
if_alt[0].altif_descr.bInterfaceClass;
404
udi_usbdev_get_subclass (udi_usb_devc * usbdev)
406
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
408
return devc->dev_data->dev_curr_cfg->cfg_if[devc->dev_data->dev_curr_if].
409
if_alt[0].altif_descr.bInterfaceSubClass;
413
udi_usbdev_get_vendor (udi_usb_devc * usbdev)
415
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
417
return devc->dev_data->dev_descr->idVendor;
421
udi_usbdev_get_product (udi_usb_devc * usbdev)
423
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
425
return devc->dev_data->dev_descr->idProduct;
429
udi_usbdev_get_inum (udi_usb_devc * usbdev)
431
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
433
return devc->dev_data->dev_curr_if;
437
udi_usbdev_set_interface (udi_usb_devc * usbdev, int inum, int altset)
439
//udi_usb_devc *devc = (udi_usb_devc *) usbdev;
441
if (usb_set_alt_if (usbdev->osdev->dip, inum, altset, USB_FLAGS_SLEEP,
442
NULL, 0) != USB_SUCCESS)
451
udi_usbdev_get_endpoint (udi_usb_devc * usbdev, int altsetting, int n,
454
usb_alt_if_data_t *altif_data;
455
usb_client_dev_data_t *dev_data;
459
if (usbdev->dev_data == NULL)
461
cmn_err (CE_WARN, "Missing USB devdata\n");
464
dev_data = usbdev->dev_data;
468
dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
473
altif_data = &dev_data->dev_curr_cfg->
474
cfg_if[dev_data->dev_curr_if].if_alt[altsetting];
476
if (altif_data == NULL)
479
if (n < 0 || n >= altif_data->altif_n_ep)
482
*len = altif_data->altif_ep[n].ep_descr.bLength;
483
return (unsigned char *) &altif_data->altif_ep[n].ep_descr;
487
udi_usbdev_get_num_altsettings (udi_usb_devc * usbdev)
489
//udi_usb_devc *devc = (udi_usb_devc *) usbdev;
490
usb_client_dev_data_t *dev_data;
492
dev_data = usbdev->dev_data;
493
return dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt;
497
udi_usbdev_get_altsetting (udi_usb_devc * usbdev, int nalt, int *size)
501
usb_alt_if_data_t *altif_data;
502
usb_client_dev_data_t *dev_data;
503
static unsigned char buf[1024];
505
dev_data = usbdev->dev_data;
506
if ((unsigned long) dev_data <= 4096)
508
cmn_err (CE_WARN, "Internal error: dev_data==NULL)\n");
514
dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
519
altif_data = &dev_data->dev_curr_cfg->
520
cfg_if[dev_data->dev_curr_if].if_alt[nalt];
522
if (altif_data == NULL)
527
for (i = 0; i < altif_data->altif_n_cvs; i++)
529
cvs = &altif_data->altif_cvs[i];
530
memcpy (buf + n, cvs->cvs_buf, cvs->cvs_buf_len);
531
n += cvs->cvs_buf_len;
534
cvs = &altif_data->altif_cvs[0];
535
if (cvs == NULL || cvs->cvs_buf == NULL)
543
udi_usbdev_get_name (udi_usb_devc * usbdev)
545
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
551
udi_usbdev_get_altsetting_labels (udi_usb_devc * usbdev, int if_num,
552
int *default_alt, unsigned int *mask)
559
if (usbdev->udi_usb_dev == NULL) /* No device definitions available */
564
for (i = 0; usbdev->udi_usb_dev->altsettings[i].altsetting_labels != NULL;
568
*default_alt = usbdev->udi_usb_dev->altsettings[i].default_altsetting;
569
*mask = usbdev->udi_usb_dev->altsettings[i].altsetting_mask;
572
return usbdev->udi_usb_dev->altsettings[i].altsetting_labels;
575
return NULL; /* Not found */
579
udi_usbdev_get_string (udi_usb_devc * usbdev, int ix)
581
static char str[256];
583
if (usb_get_string_descr
584
(usbdev->osdev->dip, USB_LANG_ID, ix, str,
585
sizeof (str) - 1) != USB_SUCCESS)
591
udi_usbdev_get_devpath (udi_usb_devc * usbdev)
593
udi_usb_devc *devc = (udi_usb_devc *) usbdev;
595
return devc->devpath;
600
udi_usb_snd_control_msg (udi_usb_devc * usbdev, unsigned int endpoint,
602
unsigned char rqtype,
603
unsigned short value,
604
unsigned short index,
605
void *buf, int len, int timeout)
610
usb_ctrl_setup_t setup;
611
usb_cr_t completion_reason;
612
usb_cb_flags_t cb_flags;
617
cmn_err (CE_CONT, "udi_usb_snd_control_msg: usbdev==NULL\n");
621
data = allocb_wait (len + 1, BPRI_HI, STR_NOSIG, NULL);
623
memcpy (data->b_wptr, buf, len);
624
data->b_wptr = data->b_rptr + len;
626
setup.bmRequestType = rqtype | USB_DEV_REQ_HOST_TO_DEV;
628
setup.wValue = value;
629
setup.wIndex = index;
633
if ((err = usb_pipe_ctrl_xfer_wait (usbdev->dev_data->dev_default_ph,
637
&cb_flags, 0)) != USB_SUCCESS)
639
char tmp[128], *s = tmp;
640
unsigned char *p = buf;
643
sprintf (s, "Msg (rq=0x%x, val=0x%04x, ix=0x%04x, len=%d): ", rq, value,
645
for (i = 0; i < len; i++)
648
sprintf (s, "%02x ", p[i]);
650
cmn_err (CE_CONT, "%s\n", tmp);
652
cmn_err (CE_NOTE, "usb_pipe_ctrl_xfer_wait write failed: %s (%s)\n",
653
usb_errstr (err), usb_cb_err (completion_reason));
654
cmn_err (CE_CONT, "bRq %x, wIx %x, wVal %x, wLen %d\n", rq, index,
666
udi_usb_rcv_control_msg (udi_usb_devc * usbdev, unsigned int endpoint,
668
unsigned char rqtype,
669
unsigned short value,
670
unsigned short index,
671
void *buf, int len, int timeout)
675
usb_ctrl_setup_t setup;
676
usb_cr_t completion_reason;
677
usb_cb_flags_t cb_flags;
682
cmn_err (CE_CONT, "udi_usb_rcv_control_msg: usbdev==NULL\n");
686
setup.bmRequestType = rqtype | USB_DEV_REQ_DEV_TO_HOST;
688
setup.wValue = value;
689
setup.wIndex = index;
693
if ((err = usb_pipe_ctrl_xfer_wait (usbdev->dev_data->dev_default_ph,
697
&cb_flags, 0)) != USB_SUCCESS)
699
char tmp[128], *s = tmp;
701
sprintf (s, "Msg (rq=0x%02x, val=0x%04x, ix=0x%04x, len=%d): ", rq,
703
cmn_err (CE_CONT, "%s\n", tmp);
704
cmn_err (CE_NOTE, "usb_pipe_ctrl_xfer_wait read failed: %s (%s)\n",
705
usb_errstr (err), usb_cb_err (completion_reason));
710
/*LINTED*/ l = data->b_wptr - data->b_rptr;
712
memcpy (buf, data->b_rptr, l);
718
/* Endpoint/pipe access */
720
struct _udi_endpoint_handle_t
722
usb_pipe_handle_t pipe_handle;
723
unsigned char *ep_desc;
724
udi_usb_devc *usbdev;
727
udi_endpoint_handle_t *
728
udi_open_endpoint (udi_usb_devc * usbdev, void *ep_desc)
730
udi_endpoint_handle_t *h;
732
usb_pipe_policy_t policy;
734
if ((h = KERNEL_MALLOC (sizeof (*h))) == NULL)
737
policy.pp_max_async_reqs = 2;
739
if ((err = usb_pipe_open (usbdev->osdev->dip, ep_desc, &policy,
740
USB_FLAGS_SLEEP, &h->pipe_handle)) != USB_SUCCESS)
742
cmn_err (CE_WARN, "usb_pipe_open() failed %d (%s)\n", err,
748
h->ep_desc = ep_desc;
755
udi_close_endpoint (udi_endpoint_handle_t * h)
757
usb_pipe_close (h->usbdev->osdev->dip, h->pipe_handle, USB_FLAGS_SLEEP,
763
udi_endpoint_get_num (udi_endpoint_handle_t * eph)
765
return eph->ep_desc[2] & 0xff;
770
struct udi_usb_request
773
usb_pipe_handle_t pipe_handle;
774
udi_usb_complete_func_t callback;
785
usb_isoc_req_t *isoc_req;
786
usb_bulk_req_t *bulk_req;
787
usb_intr_req_t *intr_req;
792
* udi_usb_alloc_request (udi_usb_devc * usbdev, udi_endpoint_handle_t * eph,
793
int nframes, int xfer_type)
795
udi_usb_request_t *req;
797
if ((req = KERNEL_MALLOC (sizeof (*req))) == NULL)
799
cmn_err (CE_WARN, "udi_usb_alloc_request: Out of memory\n");
803
req->xfer_type = xfer_type;
804
req->dip = usbdev->osdev->dip;
805
req->pipe_handle = eph->pipe_handle;
809
case UDI_USBXFER_ISO_READ:
813
case UDI_USBXFER_ISO_WRITE:
817
case UDI_USBXFER_BULK_READ:
821
case UDI_USBXFER_INTR_READ:
825
case UDI_USBXFER_BULK_WRITE:
830
cmn_err (CE_WARN, "Internal error - bad transfer type %d\n", xfer_type);
837
udi_usb_free_request (udi_usb_request_t * req)
842
udi_usb_cancel_request (req);
846
cmn_err (CE_WARN, "Warning: Freeing active request\n");
849
switch (req->xfer_type)
851
case UDI_USBXFER_ISO_WRITE:
852
req->isoc_req = NULL;
855
case UDI_USBXFER_ISO_READ:
856
req->isoc_req = NULL;
859
case UDI_USBXFER_BULK_WRITE:
860
req->bulk_req = NULL;
863
case UDI_USBXFER_BULK_READ:
864
req->bulk_req = NULL;
867
case UDI_USBXFER_INTR_READ:
868
req->intr_req = NULL;
872
cmn_err (CE_WARN, "Internal error - bad transfer type %d\n",
881
isoc_play_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
883
udi_usb_request_t *req =
884
(udi_usb_request_t *) isoc_req->isoc_client_private;
886
usb_free_isoc_req (isoc_req);
888
req->isoc_req = NULL;
891
req->callback (req, req->callback_arg);
896
isoc_rec_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
899
udi_usb_request_t *req =
900
(udi_usb_request_t *) isoc_req->isoc_client_private;
902
req->data = isoc_req->isoc_data;
904
for (i = 0; i < isoc_req->isoc_pkts_count; i++)
908
len = isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length;
912
req->callback (req, req->callback_arg);
914
req->data->b_rptr += len;
918
usb_free_isoc_req (isoc_req);
923
isoc_exc_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
925
udi_usb_request_t *req =
926
(udi_usb_request_t *) isoc_req->isoc_client_private;
929
reason = isoc_req->isoc_completion_reason;
931
usb_free_isoc_req (isoc_req);
932
req->isoc_req = NULL;
935
if (reason && reason != USB_CR_FLUSHED && reason != USB_CR_PIPE_CLOSING)
936
cmn_err (CE_CONT, "USB isoc transfer completion status %s\n",
937
usb_cr_err (reason));
942
bulk_play_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
944
udi_usb_request_t *req =
945
(udi_usb_request_t *) bulk_req->bulk_client_private;
947
usb_free_bulk_req (bulk_req);
949
req->bulk_req = NULL;
952
req->callback (req, req->callback_arg);
957
bulk_rec_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
959
udi_usb_request_t *req =
960
(udi_usb_request_t *) bulk_req->bulk_client_private;
962
req->data = bulk_req->bulk_data;
963
req->actlen = bulk_req->bulk_len;
966
req->callback (req, req->callback_arg);
967
//usb_free_bulk_req (bulk_req);
972
bulk_exc_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
974
udi_usb_request_t *req =
975
(udi_usb_request_t *) bulk_req->bulk_client_private;
978
reason = bulk_req->bulk_completion_reason;
980
usb_free_bulk_req (bulk_req);
981
req->bulk_req = NULL;
984
if (reason && reason != USB_CR_FLUSHED && reason != USB_CR_PIPE_CLOSING)
985
cmn_err (CE_CONT, "USB bulk transfer completion status %s\n",
986
usb_cr_err (reason));
991
intr_rec_callback (usb_pipe_handle_t ph, usb_intr_req_t * intr_req)
993
udi_usb_request_t *req =
994
(udi_usb_request_t *) intr_req->intr_client_private;
996
req->data = intr_req->intr_data;
997
req->actlen = intr_req->intr_len;
1000
req->callback (req, req->callback_arg);
1001
//usb_free_intr_req (intr_req);
1006
intr_exc_callback (usb_pipe_handle_t ph, usb_intr_req_t * intr_req)
1008
udi_usb_request_t *req =
1009
(udi_usb_request_t *) intr_req->intr_client_private;
1012
reason = intr_req->intr_completion_reason;
1014
usb_free_intr_req (intr_req);
1015
req->intr_req = NULL;
1018
if (reason && reason != USB_CR_FLUSHED && reason != USB_CR_PIPE_CLOSING)
1019
cmn_err (CE_CONT, "USB intr transfer completion status %s\n",
1020
usb_cr_err (reason));
1025
udi_usb_submit_request (udi_usb_request_t * req,
1026
udi_usb_complete_func_t callback, void *callback_arg,
1027
udi_endpoint_handle_t * eph, int xfer_type,
1028
void *data, int len)
1032
req->callback = callback;
1033
req->callback_arg = callback_arg;
1040
case UDI_USBXFER_ISO_WRITE:
1042
usb_isoc_req_t *isoc_req;
1044
if (req->isoc_req != NULL)
1045
isoc_req = req->isoc_req;
1048
req->data = allocb (len, BPRI_HI);
1049
if (req->data == NULL)
1051
cmn_err (CE_WARN, "allocb_wait (isoc) failed\n");
1056
if ((isoc_req = usb_alloc_isoc_req (req->dip, 1, 0, 0)) == NULL)
1058
cmn_err (CE_WARN, "usb_alloc_isoc_req failed\n");
1059
freemsg (req->data);
1063
req->isoc_req = isoc_req;
1066
if (isoc_req == NULL)
1068
cmn_err (CE_WARN, "req->isoc==NULL\n");
1072
memcpy (req->data->b_wptr, data, len);
1073
req->data->b_wptr += len;
1075
isoc_req->isoc_data = req->data;
1076
isoc_req->isoc_pkt_descr[0].isoc_pkt_length = len;
1077
isoc_req->isoc_pkts_count = 1;
1078
isoc_req->isoc_pkts_length = len;
1079
isoc_req->isoc_attributes =
1080
USB_ATTRS_ISOC_XFER_ASAP | USB_ATTRS_AUTOCLEARING;
1081
isoc_req->isoc_cb = isoc_play_callback;
1082
isoc_req->isoc_exc_cb = isoc_exc_callback;
1083
isoc_req->isoc_client_private = (usb_opaque_t) req;
1086
usb_pipe_isoc_xfer (req->pipe_handle, isoc_req,
1089
cmn_err (CE_WARN, "usb_pipe_isoc_xfer failed (%s)\n",
1097
case UDI_USBXFER_ISO_READ:
1099
usb_isoc_req_t *isoc_req;
1101
if (req->isoc_req != NULL)
1102
isoc_req = req->isoc_req;
1106
usb_alloc_isoc_req (req->dip, 1, len,
1107
USB_FLAGS_SLEEP)) == NULL)
1109
cmn_err (CE_WARN, "usb_alloc_isoc_req failed\n");
1113
req->isoc_req = isoc_req;
1116
if (isoc_req == NULL)
1118
cmn_err (CE_WARN, "req->isoc==NULL\n");
1122
isoc_req->isoc_attributes = USB_ATTRS_ISOC_XFER_ASAP;
1123
isoc_req->isoc_cb = isoc_rec_callback;
1124
isoc_req->isoc_exc_cb = isoc_exc_callback;
1125
isoc_req->isoc_client_private = (usb_opaque_t) req;
1126
isoc_req->isoc_pkt_descr[0].isoc_pkt_length = len;
1127
isoc_req->isoc_pkts_count = 1;
1128
isoc_req->isoc_pkts_length = len;
1132
usb_pipe_isoc_xfer (req->pipe_handle, isoc_req,
1133
USB_FLAGS_NOSLEEP)) != USB_SUCCESS)
1135
cmn_err (CE_WARN, "usb_pipe_isoc_xfer failed (%s)\n",
1142
case UDI_USBXFER_BULK_WRITE:
1144
usb_bulk_req_t *bulk_req;
1146
if (req->bulk_req != NULL)
1147
bulk_req = req->bulk_req;
1150
req->data = allocb (len, BPRI_HI);
1151
if (req->data == NULL)
1153
cmn_err (CE_WARN, "allocb_wait (bulk) failed\n");
1158
if ((bulk_req = usb_alloc_bulk_req (req->dip, len, 0)) == NULL)
1160
cmn_err (CE_WARN, "usb_alloc_bulk_req failed\n");
1161
freemsg (req->data);
1165
req->bulk_req = bulk_req;
1168
if (bulk_req == NULL)
1170
cmn_err (CE_WARN, "req->bulk==NULL\n");
1174
memcpy (req->data->b_wptr, data, len);
1175
req->data->b_wptr += len;
1177
bulk_req->bulk_data = req->data;
1178
bulk_req->bulk_len = len;
1179
bulk_req->bulk_timeout = 5; /* 5 seconds */
1180
bulk_req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
1181
bulk_req->bulk_cb = bulk_play_callback;
1182
bulk_req->bulk_exc_cb = bulk_exc_callback;
1183
bulk_req->bulk_client_private = (usb_opaque_t) req;
1186
usb_pipe_bulk_xfer (req->pipe_handle, bulk_req,
1189
cmn_err (CE_WARN, "usb_pipe_bulk_xfer failed (%s)\n",
1197
case UDI_USBXFER_BULK_READ:
1199
usb_bulk_req_t *bulk_req;
1201
if (req->bulk_req != NULL)
1202
bulk_req = req->bulk_req;
1206
req->data = allocb (len, BPRI_HI);
1207
if (req->data == NULL)
1209
cmn_err (CE_WARN, "allocb_wait (bulk) failed\n");
1216
usb_alloc_bulk_req (req->dip, len, USB_FLAGS_SLEEP)) == NULL)
1218
cmn_err (CE_WARN, "usb_alloc_bulk_req failed\n");
1219
freemsg (req->data);
1223
req->bulk_req = bulk_req;
1226
if (bulk_req == NULL)
1228
cmn_err (CE_WARN, "req->bulk==NULL\n");
1232
bulk_req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK;
1233
bulk_req->bulk_cb = bulk_rec_callback;
1234
bulk_req->bulk_exc_cb = bulk_exc_callback;
1235
bulk_req->bulk_client_private = (usb_opaque_t) req;
1236
// bulk_req->bulk_data = data;
1237
bulk_req->bulk_len = len;
1238
bulk_req->bulk_timeout = 0x7fffffff; /* As long as possible */
1242
usb_pipe_bulk_xfer (req->pipe_handle, bulk_req,
1243
USB_FLAGS_NOSLEEP)) != USB_SUCCESS)
1245
cmn_err (CE_WARN, "usb_pipe_bulk_xfer failed (%s)\n",
1252
case UDI_USBXFER_INTR_READ:
1254
usb_intr_req_t *intr_req;
1256
if (req->intr_req != NULL)
1257
intr_req = req->intr_req;
1261
req->data = allocb (len, BPRI_HI);
1262
if (req->data == NULL)
1264
cmn_err (CE_WARN, "allocb_wait (intr) failed\n");
1271
usb_alloc_intr_req (req->dip, len, USB_FLAGS_SLEEP)) == NULL)
1273
cmn_err (CE_WARN, "usb_alloc_intr_req failed\n");
1274
freemsg (req->data);
1278
req->intr_req = intr_req;
1281
if (intr_req == NULL)
1283
cmn_err (CE_WARN, "req->intr==NULL\n");
1287
intr_req->intr_attributes =
1288
USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_ONE_XFER;
1289
intr_req->intr_cb = intr_rec_callback;
1290
intr_req->intr_exc_cb = intr_exc_callback;
1291
intr_req->intr_client_private = (usb_opaque_t) req;
1292
intr_req->intr_data = NULL;
1293
intr_req->intr_len = len;
1294
intr_req->intr_timeout = 0x7fffffff; /* As long as possible */
1298
usb_pipe_intr_xfer (req->pipe_handle, intr_req,
1301
cmn_err (CE_WARN, "usb_pipe_intr_xfer failed (%s)\n",
1309
cmn_err (CE_WARN, "Unimplemented transfer type %d\n", xfer_type);
1317
udi_usb_request_actlen (udi_usb_request_t * request)
1319
return request->actlen;
1323
udi_usb_request_actdata (udi_usb_request_t * request)
1325
return request->data->b_rptr;
1329
udi_usb_cancel_request (udi_usb_request_t * req)
1331
if (req == NULL || !req->active)
1335
usb_pipe_reset (req->dip, req->pipe_handle, USB_FLAGS_SLEEP, NULL, 0);
1337
switch (req->xfer_type)
1339
case UDI_USBXFER_ISO_WRITE:
1342
case UDI_USBXFER_ISO_READ:
1343
usb_pipe_stop_isoc_polling (req->pipe_handle, USB_FLAGS_SLEEP);
1344
//if (req->isoc_req!=NULL)
1345
//usb_free_isoc_req(req->isoc_req);
1346
req->isoc_req = NULL;
1349
case UDI_USBXFER_BULK_WRITE:
1352
case UDI_USBXFER_BULK_READ:
1353
req->bulk_req = NULL;
1356
case UDI_USBXFER_INTR_READ:
1357
req->intr_req = NULL;
1361
cmn_err (CE_WARN, "Internal error - bad transfer type %d\n",