~ubuntu-branches/ubuntu/vivid/oss4/vivid-proposed

« back to all changes in this revision

Viewing changes to kernel/OS/SunOS/udi.c

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis, Samuel Thibault, Romain Beauxis, Sebastien NOEL
  • Date: 2011-06-14 10:06:56 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110614100656-cx4oc7u426zn812z
Tags: 4.2-build2004-1
[ Samuel Thibault ]
* debian/control: Add liboss4-salsa2, liboss4-salsa-dev and
  liboss4-salsa-asound2 packages, equivalent to (and will replace) those from
  the oss-libsalsa package (Closes: #589127).
* debian/patches/liboss4-salsa.patch: New patch to rename libsalsa into
  liboss4-salsa to avoid conflicts in the archive for no good reason.
* debian/rules: Make in libOSSlib and libsalsa.
* debian/liboss4-salsa-dev.install, debian/liboss4-salsa2.install,
  debian/liboss4-salsa-asound2.links, debian/liboss4-salsa-dev.links:
  Install liboss4-salsa libraries like was done in the oss-libsalsa package.
* include-alsa: Add a copy of ALSA 1.0.5 headers: Cf ALSA_1.0.* symbols in
  libsalsa, this is the roughly supported version.
* debian/copyright: Update for new include-alsa files.
* alsa.pc: New file for compatibility with libasound-dev.
* debian/control:
  - Add Vcs-Browser and Vcs-Svn fields.
  - Use linux-any instead of the list of Linux archs (Closes: #604679).
  - Make dkms dependency linux-any only.
* debian/patches/hurd_iot.patch: New patch to fix soundcard.h usage in
  libsalsa on hurd-i386.
* debian/patches/libsalsa_fixes.patch: New patch to fix some printf usages
  and ioctl declaration in libsalsa.
* debian/patches/no_EBADE.patch: New patch to cope with hurd-i386 not having
  EBADE.
* debian/patches/CFLAGS.patch: New patch to make oss4 take debian/rules
  CFLAGS into account.
* debian/patches/snd_asoundlib_version.patch: New patch to add
  snd_asoundlib_version().
* debian/patches/generic_srccconf.patch: New patch to fix source
  configuration on unknown archs.

[ Romain Beauxis ]
* Fixed README.Debian to only mention dkms' modules.
* Switch to dpkg-source 3.0 (quilt) format
* Added DM-Upload-Allowed: yes

[ Sebastien NOEL ]
* New upstream release (Closes: #595298, #619272).
* Fix typo in initscript (Closes: #627149).
* debian/control: adjust linux-headers dependencies (Closes: #628879).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: USB device interface (udi.h) routines for Solaris
 
3
 */
 
4
/*
 
5
 *
 
6
 * This file is part of Open Sound System.
 
7
 *
 
8
 * Copyright (C) 4Front Technologies 1996-2008.
 
9
 *
 
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.
 
13
 *
 
14
 */
 
15
#if !defined(SOL9)
 
16
#include "oss_config.h"
 
17
#include <udi.h>
 
18
 
 
19
#define USBDRV_MAJOR_VER        2
 
20
#define USBDRV_MINOR_VER        0
 
21
#include <sys/usb/usba.h>
 
22
#include <sys/strsubr.h>
 
23
 
 
24
#undef IO_DEBUG
 
25
int udi_usb_trace = 0;
 
26
 
 
27
#define MAX_DEVICE_SLOTS 20
 
28
 
 
29
struct udi_usb_devc
 
30
{
 
31
  oss_device_t *osdev;
 
32
  usb_client_dev_data_t *dev_data;
 
33
  char *name;
 
34
 
 
35
  const struct usb_device_id *id;
 
36
  const udi_usb_devinfo *udi_usb_dev;
 
37
  char devpath[32];
 
38
 
 
39
  int enabled;
 
40
 
 
41
  struct usb_interface *iface;
 
42
  udi_usb_driver *drv;
 
43
  void *client_devc;
 
44
  void (*client_disconnect) (void *devc);
 
45
};
 
46
 
 
47
#define MAX_DEVC 32
 
48
 
 
49
int
 
50
udi_attach_usbdriver (oss_device_t * osdev, const udi_usb_devinfo * devlist,
 
51
                      udi_usb_driver * driver)
 
52
{
 
53
  int err, i, nalt, vendor, product, busaddr;
 
54
  udi_usb_devc *usbdev;
 
55
  dev_info_t *dip = osdev->dip;
 
56
  char *name;
 
57
  unsigned long osid;
 
58
  //usb_alt_if_data_t *altif_data;
 
59
  usb_client_dev_data_t *dev_data;
 
60
 
 
61
  if (dip==NULL)
 
62
     {
 
63
        cmn_err(CE_WARN, "dip==NULL\n");
 
64
        return 0;
 
65
     }
 
66
 
 
67
  name = ddi_get_name (osdev->dip);
 
68
 
 
69
  if (strcmp (name, "oss_usb") == 0)
 
70
    {
 
71
      oss_register_device (osdev, "USB audio/MIDI device");
 
72
      return 1;
 
73
    }
 
74
 
 
75
  /*
 
76
   * Select the default configuration
 
77
   */
 
78
  if ((err = usb_set_cfg (osdev->dip, USB_DEV_DEFAULT_CONFIG_INDEX,
 
79
                          USB_FLAGS_SLEEP, NULL, NULL)) == USB_SUCCESS)
 
80
    {
 
81
      cmn_err (CE_CONT, "usb_set_cfg returned %d\n", err);
 
82
    }
 
83
 
 
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)
 
87
    {
 
88
      cmn_err (CE_WARN, "udi_attach_usbdriver: Out of memory\n");
 
89
      return 0;
 
90
    }
 
91
 
 
92
  memset (usbdev, 0, sizeof (*usbdev));
 
93
  osdev->usbdev = usbdev;
 
94
  usbdev->osdev = osdev;
 
95
 
 
96
  if ((err = usb_client_attach (dip, USBDRV_VERSION, 0)) != USB_SUCCESS)
 
97
    {
 
98
      cmn_err (CE_WARN, "usb_client_attach failed, err=%d\n", err);
 
99
      KERNEL_FREE (usbdev);
 
100
      return 0;
 
101
    }
 
102
 
 
103
  if ((err =
 
104
       usb_get_dev_data (osdev->dip, &usbdev->dev_data, USB_PARSE_LVL_CFG,
 
105
                         0)) != USB_SUCCESS)
 
106
    {
 
107
      cmn_err (CE_WARN, "usb_get_dev_data failed, err=%d\n", err);
 
108
      KERNEL_FREE (usbdev);
 
109
      return 0;
 
110
    }
 
111
  dev_data = usbdev->dev_data;
 
112
 
 
113
  osdev->iblock_cookie = dev_data->dev_iblock_cookie;
 
114
 
 
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);
 
120
 
 
121
#if 0
 
122
  if (udi_usb_trace > 5)
 
123
    usb_print_descr_tree (osdev->dip, dev_data);
 
124
#endif
 
125
 
 
126
  nalt = 1;
 
127
  if (nalt >= dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
 
128
    nalt = 0;
 
129
 
 
130
  //altif_data = &dev_data->dev_curr_cfg->
 
131
  //  cfg_if[dev_data->dev_curr_if].if_alt[nalt];
 
132
 
 
133
  usbdev->name = usbdev->dev_data->dev_product;
 
134
  vendor = udi_usbdev_get_vendor (usbdev);
 
135
  product = udi_usbdev_get_product (usbdev);
 
136
 
 
137
  /* inum = usbdev->dev_data->dev_curr_if; */
 
138
  osid = (vendor << 16) | product;
 
139
  osdev->osid = (void *) osid;
 
140
 
 
141
  sprintf (osdev->handle, "usb%x,%x.%d:%d", vendor, product,
 
142
           dev_data->dev_curr_if, osdev->instance);
 
143
 
 
144
  for (i = 0; devlist[i].vendor != -1; i++)
 
145
    if (devlist[i].vendor == vendor && devlist[i].product == product)
 
146
      {
 
147
        usbdev->name = devlist[i].name;
 
148
        usbdev->udi_usb_dev = &devlist[i];
 
149
        oss_register_device (osdev, usbdev->name);
 
150
        break;
 
151
      }
 
152
 
 
153
  if ((usbdev->client_devc = driver->attach (usbdev, osdev)) == NULL)
 
154
    {
 
155
      cmn_err (CE_WARN, "Client attach failed, err=%d\n", err);
 
156
      udi_unload_usbdriver (osdev);
 
157
      return 0;
 
158
    }
 
159
 
 
160
  usbdev->client_disconnect = driver->disconnect;
 
161
 
 
162
  return 1;
 
163
}
 
164
 
 
165
static char *
 
166
usb_errstr (int err)
 
167
{
 
168
 
 
169
  static struct errmsg_
 
170
  {
 
171
    int err;
 
172
    char *str;
 
173
  } errs[] =
 
174
  {
 
175
    {
 
176
    USB_FAILURE, "USB_FAILURE"},
 
177
    {
 
178
    USB_NO_RESOURCES, "USB_NO_RESOURCES"},
 
179
    {
 
180
    USB_NO_BANDWIDTH, "USB_NO_BANDWIDTH"},
 
181
    {
 
182
    USB_NOT_SUPPORTED, "USB_NOT_SUPPORTED"},
 
183
    {
 
184
    USB_PIPE_ERROR, "USB_PIPE_ERROR"},
 
185
    {
 
186
    USB_INVALID_PIPE, "USB_INVALID_PIPE"},
 
187
    {
 
188
    USB_NO_FRAME_NUMBER, "USB_NO_FRAME_NUMBER"},
 
189
    {
 
190
    USB_INVALID_START_FRAME, "USB_INVALID_START_FRAME"},
 
191
    {
 
192
    USB_HC_HARDWARE_ERROR, "USB_HC_HARDWARE_ERROR"},
 
193
    {
 
194
    USB_INVALID_REQUEST, "USB_INVALID_REQUEST"},
 
195
    {
 
196
    USB_INVALID_CONTEXT, "USB_INVALID_CONTEXT"},
 
197
    {
 
198
    USB_INVALID_VERSION, "USB_INVALID_VERSION"},
 
199
    {
 
200
    USB_INVALID_ARGS, "USB_INVALID_ARGS"},
 
201
    {
 
202
    USB_INVALID_PERM, "USB_INVALID_PERM"},
 
203
    {
 
204
    USB_BUSY, "USB_BUSY"},
 
205
    {
 
206
    0, NULL}
 
207
  };
 
208
 
 
209
  int i;
 
210
  static char msg[20];
 
211
 
 
212
  for (i = 0; errs[i].err != 0; i++)
 
213
    if (errs[i].err == err)
 
214
      {
 
215
        return errs[i].str;
 
216
      }
 
217
 
 
218
  sprintf (msg, "Err %d", err);
 
219
  return msg;
 
220
}
 
221
 
 
222
static char *
 
223
usb_cb_err (int err)
 
224
{
 
225
 
 
226
  static struct errmsg_
 
227
  {
 
228
    int err;
 
229
    char *str;
 
230
  } errs[] =
 
231
  {
 
232
    {
 
233
    USB_CB_STALL_CLEARED, "USB_CB_STALL_CLEARED"},
 
234
    {
 
235
    USB_CB_FUNCTIONAL_STALL, "USB_CB_FUNCTIONAL_STALL"},
 
236
    {
 
237
    USB_CB_PROTOCOL_STALL, "USB_CB_PROTOCOL_STALL"},
 
238
    {
 
239
    USB_CB_RESET_PIPE, "USB_CB_RESET_PIPE"},
 
240
    {
 
241
    USB_CB_ASYNC_REQ_FAILED, "USB_CB_ASYNC_REQ_FAILED"},
 
242
    {
 
243
    USB_CB_NO_RESOURCES, "USB_CB_NO_RESOURCES"},
 
244
    {
 
245
    USB_CB_SUBMIT_FAILED, "USB_CB_SUBMIT_FAILED"},
 
246
    {
 
247
    USB_CB_INTR_CONTEXT, "USB_CB_INTR_CONTEXT"},
 
248
    {
 
249
    USB_FAILURE, "USB_FAILURE"},
 
250
    {
 
251
    USB_NO_RESOURCES, "USB_NO_RESOURCES"},
 
252
    {
 
253
    USB_NO_BANDWIDTH, "USB_NO_BANDWIDTH"},
 
254
    {
 
255
    USB_NOT_SUPPORTED, "USB_NOT_SUPPORTED"},
 
256
    {
 
257
    USB_PIPE_ERROR, "USB_PIPE_ERROR"},
 
258
    {
 
259
    USB_INVALID_PIPE, "USB_INVALID_PIPE"},
 
260
    {
 
261
    USB_NO_FRAME_NUMBER, "USB_NO_FRAME_NUMBER"},
 
262
    {
 
263
    USB_INVALID_START_FRAME, "USB_INVALID_START_FRAME"},
 
264
    {
 
265
    USB_HC_HARDWARE_ERROR, "USB_HC_HARDWARE_ERROR"},
 
266
    {
 
267
    USB_INVALID_REQUEST, "USB_INVALID_REQUEST"},
 
268
    {
 
269
    USB_INVALID_CONTEXT, "USB_INVALID_CONTEXT"},
 
270
    {
 
271
    USB_INVALID_VERSION, "USB_INVALID_VERSION"},
 
272
    {
 
273
    USB_INVALID_ARGS, "USB_INVALID_ARGS"},
 
274
    {
 
275
    USB_INVALID_PERM, "USB_INVALID_PERM"},
 
276
    {
 
277
    USB_BUSY, "USB_BUSY"},
 
278
    {
 
279
    0, NULL}
 
280
  };
 
281
 
 
282
  int i;
 
283
  static char msg[20];
 
284
 
 
285
  if (err == 0)
 
286
    return "USB_CB_NO_INFO";
 
287
 
 
288
  for (i = 0; errs[i].err != 0; i++)
 
289
    {
 
290
      if (errs[i].err == err)
 
291
        {
 
292
          return errs[i].str;
 
293
        }
 
294
    }
 
295
 
 
296
  sprintf (msg, "CB Err %d", err);
 
297
  return msg;
 
298
}
 
299
 
 
300
static char *
 
301
usb_cr_err (int err)
 
302
{
 
303
 
 
304
  static struct errmsg_
 
305
  {
 
306
    int err;
 
307
    char *str;
 
308
  } errs[] =
 
309
  {
 
310
    {
 
311
    USB_CR_CRC, "USB_CR_CRC"},
 
312
    {
 
313
    USB_CR_BITSTUFFING, "USB_CR_BITSTUFFING"},
 
314
    {
 
315
    USB_CR_DATA_TOGGLE_MM, "USB_CR_DATA_TOGGLE_MM"},
 
316
    {
 
317
    USB_CR_STALL, "USB_CR_STALL"},
 
318
    {
 
319
    USB_CR_DEV_NOT_RESP, "USB_CR_DEV_NOT_RESP"},
 
320
    {
 
321
    USB_CR_PID_CHECKFAILURE, "USB_CR_PID_CHECKFAILURE"},
 
322
    {
 
323
    USB_CR_UNEXP_PID, "USB_CR_UNEXP_PID"},
 
324
    {
 
325
    USB_CR_DATA_OVERRUN, "USB_CR_DATA_OVERRUN"},
 
326
    {
 
327
    USB_CR_DATA_UNDERRUN, "USB_CR_DATA_UNDERRUN"},
 
328
    {
 
329
    USB_CR_BUFFER_OVERRUN, "USB_CR_BUFFER_OVERRUN"},
 
330
    {
 
331
    USB_CR_BUFFER_UNDERRUN, "USB_CR_BUFFER_UNDERRUN"},
 
332
    {
 
333
    USB_CR_TIMEOUT, "USB_CR_TIMEOUT"},
 
334
    {
 
335
    USB_CR_NOT_ACCESSED, "USB_CR_NOT_ACCESSED"},
 
336
    {
 
337
    USB_CR_NO_RESOURCES, "USB_CR_NO_RESOURCES"},
 
338
    {
 
339
    USB_CR_UNSPECIFIED_ERR, "USB_CR_UNSPECIFIED_ERR"},
 
340
    {
 
341
    USB_CR_STOPPED_POLLING, "USB_CR_STOPPED_POLLING"},
 
342
    {
 
343
    USB_CR_PIPE_CLOSING, "USB_CR_PIPE_CLOSING"},
 
344
    {
 
345
    USB_CR_PIPE_RESET, "USB_CR_PIPE_RESET"},
 
346
    {
 
347
    USB_CR_NOT_SUPPORTED, "USB_CR_NOT_SUPPORTED"},
 
348
    {
 
349
    USB_CR_FLUSHED, "USB_CR_FLUSHED"},
 
350
    {
 
351
    USB_CR_HC_HARDWARE_ERR, "USB_CR_HC_HARDWARE_ERR"},
 
352
    {
 
353
    0, NULL}
 
354
  };
 
355
 
 
356
  int i;
 
357
  static char msg[20];
 
358
 
 
359
  if (err == 0)
 
360
    return "USB_CR_OK";
 
361
 
 
362
  for (i = 0; errs[i].err != 0; i++)
 
363
    {
 
364
      if (errs[i].err == err)
 
365
        {
 
366
          return errs[i].str;
 
367
        }
 
368
    }
 
369
 
 
370
  sprintf (msg, "CR Err %d", err);
 
371
  return msg;
 
372
}
 
373
 
 
374
void
 
375
udi_unload_usbdriver (oss_device_t * osdev)
 
376
{
 
377
  udi_usb_devc *usbdev = osdev->usbdev;
 
378
 
 
379
  if (usbdev == NULL)
 
380
    return;
 
381
 
 
382
  if (usbdev->client_disconnect != NULL)
 
383
    usbdev->client_disconnect (usbdev->client_devc);
 
384
  usb_client_detach (osdev->dip, usbdev->dev_data);
 
385
 
 
386
  KERNEL_FREE (usbdev);
 
387
  osdev->usbdev = NULL;
 
388
}
 
389
 
 
390
/* 
 
391
 * Device access routines
 
392
 */
 
393
 
 
394
int
 
395
udi_usbdev_get_class (udi_usb_devc * usbdev)
 
396
{
 
397
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
398
 
 
399
  return devc->dev_data->dev_curr_cfg->cfg_if[devc->dev_data->dev_curr_if].
 
400
    if_alt[0].altif_descr.bInterfaceClass;
 
401
}
 
402
 
 
403
int
 
404
udi_usbdev_get_subclass (udi_usb_devc * usbdev)
 
405
{
 
406
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
407
 
 
408
  return devc->dev_data->dev_curr_cfg->cfg_if[devc->dev_data->dev_curr_if].
 
409
    if_alt[0].altif_descr.bInterfaceSubClass;
 
410
}
 
411
 
 
412
int
 
413
udi_usbdev_get_vendor (udi_usb_devc * usbdev)
 
414
{
 
415
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
416
 
 
417
  return devc->dev_data->dev_descr->idVendor;
 
418
}
 
419
 
 
420
int
 
421
udi_usbdev_get_product (udi_usb_devc * usbdev)
 
422
{
 
423
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
424
 
 
425
  return devc->dev_data->dev_descr->idProduct;
 
426
}
 
427
 
 
428
int
 
429
udi_usbdev_get_inum (udi_usb_devc * usbdev)
 
430
{
 
431
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
432
 
 
433
  return devc->dev_data->dev_curr_if;
 
434
}
 
435
 
 
436
int
 
437
udi_usbdev_set_interface (udi_usb_devc * usbdev, int inum, int altset)
 
438
{
 
439
  //udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
440
 
 
441
  if (usb_set_alt_if (usbdev->osdev->dip, inum, altset, USB_FLAGS_SLEEP,
 
442
                      NULL, 0) != USB_SUCCESS)
 
443
    {
 
444
      return OSS_EIO;
 
445
    }
 
446
 
 
447
  return 0;
 
448
}
 
449
 
 
450
unsigned char *
 
451
udi_usbdev_get_endpoint (udi_usb_devc * usbdev, int altsetting, int n,
 
452
                         int *len)
 
453
{
 
454
  usb_alt_if_data_t *altif_data;
 
455
  usb_client_dev_data_t *dev_data;
 
456
 
 
457
  *len = 0;
 
458
 
 
459
  if (usbdev->dev_data == NULL)
 
460
    {
 
461
      cmn_err (CE_WARN, "Missing USB devdata\n");
 
462
      return NULL;
 
463
    }
 
464
  dev_data = usbdev->dev_data;
 
465
 
 
466
  if (altsetting < 0
 
467
      || altsetting >=
 
468
      dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
 
469
    {
 
470
      return NULL;
 
471
    }
 
472
 
 
473
  altif_data = &dev_data->dev_curr_cfg->
 
474
    cfg_if[dev_data->dev_curr_if].if_alt[altsetting];
 
475
 
 
476
  if (altif_data == NULL)
 
477
    return NULL;
 
478
 
 
479
  if (n < 0 || n >= altif_data->altif_n_ep)
 
480
    return NULL;
 
481
 
 
482
  *len = altif_data->altif_ep[n].ep_descr.bLength;
 
483
  return (unsigned char *) &altif_data->altif_ep[n].ep_descr;
 
484
}
 
485
 
 
486
int
 
487
udi_usbdev_get_num_altsettings (udi_usb_devc * usbdev)
 
488
{
 
489
  //udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
490
  usb_client_dev_data_t *dev_data;
 
491
 
 
492
  dev_data = usbdev->dev_data;
 
493
  return dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt;
 
494
}
 
495
 
 
496
unsigned char *
 
497
udi_usbdev_get_altsetting (udi_usb_devc * usbdev, int nalt, int *size)
 
498
{
 
499
  int i, n;
 
500
  usb_cvs_data_t *cvs;
 
501
  usb_alt_if_data_t *altif_data;
 
502
  usb_client_dev_data_t *dev_data;
 
503
  static unsigned char buf[1024];
 
504
 
 
505
  dev_data = usbdev->dev_data;
 
506
  if ((unsigned long) dev_data <= 4096)
 
507
    {
 
508
      cmn_err (CE_WARN, "Internal error: dev_data==NULL)\n");
 
509
      return NULL;
 
510
    }
 
511
 
 
512
  if (nalt < 0
 
513
      || nalt >=
 
514
      dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
 
515
    {
 
516
      return NULL;
 
517
    }
 
518
 
 
519
  altif_data = &dev_data->dev_curr_cfg->
 
520
    cfg_if[dev_data->dev_curr_if].if_alt[nalt];
 
521
 
 
522
  if (altif_data == NULL)
 
523
    return NULL;
 
524
 
 
525
  n = 0;
 
526
 
 
527
  for (i = 0; i < altif_data->altif_n_cvs; i++)
 
528
    {
 
529
      cvs = &altif_data->altif_cvs[i];
 
530
      memcpy (buf + n, cvs->cvs_buf, cvs->cvs_buf_len);
 
531
      n += cvs->cvs_buf_len;
 
532
    }
 
533
 
 
534
  cvs = &altif_data->altif_cvs[0];
 
535
  if (cvs == NULL || cvs->cvs_buf == NULL)
 
536
    return NULL;
 
537
 
 
538
  *size = n;
 
539
  return buf;
 
540
}
 
541
 
 
542
char *
 
543
udi_usbdev_get_name (udi_usb_devc * usbdev)
 
544
{
 
545
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
546
 
 
547
  return devc->name;
 
548
}
 
549
 
 
550
char *
 
551
udi_usbdev_get_altsetting_labels (udi_usb_devc * usbdev, int if_num,
 
552
                                  int *default_alt, unsigned int *mask)
 
553
{
 
554
  int i;
 
555
 
 
556
  *default_alt = 1;
 
557
  *mask = 0xffffffff;
 
558
 
 
559
  if (usbdev->udi_usb_dev == NULL)      /* No device definitions available */
 
560
    {
 
561
      return NULL;
 
562
    }
 
563
 
 
564
  for (i = 0; usbdev->udi_usb_dev->altsettings[i].altsetting_labels != NULL;
 
565
       i++)
 
566
    if (i == if_num)
 
567
      {
 
568
        *default_alt = usbdev->udi_usb_dev->altsettings[i].default_altsetting;
 
569
        *mask = usbdev->udi_usb_dev->altsettings[i].altsetting_mask;
 
570
        if (*mask == 0)
 
571
          *mask = 0xffffffff;
 
572
        return usbdev->udi_usb_dev->altsettings[i].altsetting_labels;
 
573
      }
 
574
 
 
575
  return NULL;                  /* Not found */
 
576
}
 
577
 
 
578
char *
 
579
udi_usbdev_get_string (udi_usb_devc * usbdev, int ix)
 
580
{
 
581
  static char str[256];
 
582
 
 
583
  if (usb_get_string_descr
 
584
      (usbdev->osdev->dip, USB_LANG_ID, ix, str,
 
585
       sizeof (str) - 1) != USB_SUCCESS)
 
586
    return NULL;
 
587
  return str;
 
588
}
 
589
 
 
590
char *
 
591
udi_usbdev_get_devpath (udi_usb_devc * usbdev)
 
592
{
 
593
  udi_usb_devc *devc = (udi_usb_devc *) usbdev;
 
594
 
 
595
  return devc->devpath;
 
596
}
 
597
 
 
598
/*ARGSUSED*/
 
599
int
 
600
udi_usb_snd_control_msg (udi_usb_devc * usbdev, unsigned int endpoint,
 
601
                         unsigned char rq,
 
602
                         unsigned char rqtype,
 
603
                         unsigned short value,
 
604
                         unsigned short index,
 
605
                         void *buf, int len, int timeout)
 
606
{
 
607
 
 
608
  int err;
 
609
 
 
610
  usb_ctrl_setup_t setup;
 
611
  usb_cr_t completion_reason;
 
612
  usb_cb_flags_t cb_flags;
 
613
  mblk_t *data = NULL;
 
614
 
 
615
  if (usbdev == NULL)
 
616
    {
 
617
      cmn_err (CE_CONT, "udi_usb_snd_control_msg: usbdev==NULL\n");
 
618
      return OSS_EFAULT;
 
619
    }
 
620
 
 
621
  data = allocb_wait (len + 1, BPRI_HI, STR_NOSIG, NULL);
 
622
 
 
623
  memcpy (data->b_wptr, buf, len);
 
624
  data->b_wptr = data->b_rptr + len;
 
625
 
 
626
  setup.bmRequestType = rqtype | USB_DEV_REQ_HOST_TO_DEV;
 
627
  setup.bRequest = rq;
 
628
  setup.wValue = value;
 
629
  setup.wIndex = index;
 
630
  setup.wLength = len;
 
631
  setup.attrs = 0;
 
632
 
 
633
  if ((err = usb_pipe_ctrl_xfer_wait (usbdev->dev_data->dev_default_ph,
 
634
                                      &setup,
 
635
                                      &data,
 
636
                                      &completion_reason,
 
637
                                      &cb_flags, 0)) != USB_SUCCESS)
 
638
    {
 
639
      char tmp[128], *s = tmp;
 
640
      unsigned char *p = buf;
 
641
      int i;
 
642
 
 
643
      sprintf (s, "Msg (rq=0x%x, val=0x%04x, ix=0x%04x, len=%d): ", rq, value,
 
644
               index, len);
 
645
      for (i = 0; i < len; i++)
 
646
        {
 
647
          s += strlen (s);
 
648
          sprintf (s, "%02x ", p[i]);
 
649
        }
 
650
      cmn_err (CE_CONT, "%s\n", tmp);
 
651
 
 
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,
 
655
               value, len);
 
656
      freemsg (data);
 
657
      return OSS_EIO;
 
658
    }
 
659
 
 
660
  freemsg (data);
 
661
  return len;
 
662
}
 
663
 
 
664
/*ARGSUSED*/
 
665
int
 
666
udi_usb_rcv_control_msg (udi_usb_devc * usbdev, unsigned int endpoint,
 
667
                         unsigned char rq,
 
668
                         unsigned char rqtype,
 
669
                         unsigned short value,
 
670
                         unsigned short index,
 
671
                         void *buf, int len, int timeout)
 
672
{
 
673
  int err, l;
 
674
 
 
675
  usb_ctrl_setup_t setup;
 
676
  usb_cr_t completion_reason;
 
677
  usb_cb_flags_t cb_flags;
 
678
  mblk_t *data = NULL;
 
679
 
 
680
  if (usbdev == NULL)
 
681
    {
 
682
      cmn_err (CE_CONT, "udi_usb_rcv_control_msg: usbdev==NULL\n");
 
683
      return OSS_EFAULT;
 
684
    }
 
685
 
 
686
  setup.bmRequestType = rqtype | USB_DEV_REQ_DEV_TO_HOST;
 
687
  setup.bRequest = rq;
 
688
  setup.wValue = value;
 
689
  setup.wIndex = index;
 
690
  setup.wLength = len;
 
691
  setup.attrs = 0;
 
692
 
 
693
  if ((err = usb_pipe_ctrl_xfer_wait (usbdev->dev_data->dev_default_ph,
 
694
                                      &setup,
 
695
                                      &data,
 
696
                                      &completion_reason,
 
697
                                      &cb_flags, 0)) != USB_SUCCESS)
 
698
    {
 
699
      char tmp[128], *s = tmp;
 
700
 
 
701
      sprintf (s, "Msg (rq=0x%02x, val=0x%04x, ix=0x%04x, len=%d): ", rq,
 
702
               value, index, len);
 
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));
 
706
      freemsg (data);
 
707
      return OSS_EIO;
 
708
    }
 
709
 
 
710
   /*LINTED*/ l = data->b_wptr - data->b_rptr;
 
711
 
 
712
  memcpy (buf, data->b_rptr, l);
 
713
  freemsg (data);
 
714
 
 
715
  return l;
 
716
}
 
717
 
 
718
/* Endpoint/pipe access */
 
719
 
 
720
struct _udi_endpoint_handle_t
 
721
{
 
722
  usb_pipe_handle_t pipe_handle;
 
723
  unsigned char *ep_desc;
 
724
  udi_usb_devc *usbdev;
 
725
};
 
726
 
 
727
udi_endpoint_handle_t *
 
728
udi_open_endpoint (udi_usb_devc * usbdev, void *ep_desc)
 
729
{
 
730
  udi_endpoint_handle_t *h;
 
731
  int err;
 
732
  usb_pipe_policy_t policy;
 
733
 
 
734
  if ((h = KERNEL_MALLOC (sizeof (*h))) == NULL)
 
735
    return NULL;
 
736
 
 
737
  policy.pp_max_async_reqs = 2;
 
738
 
 
739
  if ((err = usb_pipe_open (usbdev->osdev->dip, ep_desc, &policy,
 
740
                            USB_FLAGS_SLEEP, &h->pipe_handle)) != USB_SUCCESS)
 
741
    {
 
742
      cmn_err (CE_WARN, "usb_pipe_open() failed %d (%s)\n", err,
 
743
               usb_cb_err (err));
 
744
      KERNEL_FREE (h);
 
745
      return NULL;
 
746
    }
 
747
 
 
748
  h->ep_desc = ep_desc;
 
749
  h->usbdev = usbdev;
 
750
 
 
751
  return h;
 
752
}
 
753
 
 
754
void
 
755
udi_close_endpoint (udi_endpoint_handle_t * h)
 
756
{
 
757
  usb_pipe_close (h->usbdev->osdev->dip, h->pipe_handle, USB_FLAGS_SLEEP,
 
758
                  NULL, 0);
 
759
  KERNEL_FREE (h);
 
760
}
 
761
 
 
762
int
 
763
udi_endpoint_get_num (udi_endpoint_handle_t * eph)
 
764
{
 
765
  return eph->ep_desc[2] & 0xff;
 
766
}
 
767
 
 
768
/* Request stuff */
 
769
 
 
770
struct udi_usb_request
 
771
{
 
772
  dev_info_t *dip;
 
773
  usb_pipe_handle_t pipe_handle;
 
774
  udi_usb_complete_func_t callback;
 
775
  void *callback_arg;
 
776
  int active;
 
777
  int xfer_type;
 
778
  mblk_t *data;
 
779
 
 
780
  /*
 
781
   * Recording
 
782
   */
 
783
  int actlen;
 
784
 
 
785
  usb_isoc_req_t *isoc_req;
 
786
  usb_bulk_req_t *bulk_req;
 
787
  usb_intr_req_t *intr_req;
 
788
};
 
789
 
 
790
 /*ARGSUSED*/
 
791
  udi_usb_request_t
 
792
  * udi_usb_alloc_request (udi_usb_devc * usbdev, udi_endpoint_handle_t * eph,
 
793
                           int nframes, int xfer_type)
 
794
{
 
795
  udi_usb_request_t *req;
 
796
 
 
797
  if ((req = KERNEL_MALLOC (sizeof (*req))) == NULL)
 
798
    {
 
799
      cmn_err (CE_WARN, "udi_usb_alloc_request: Out of memory\n");
 
800
      return NULL;
 
801
    }
 
802
 
 
803
  req->xfer_type = xfer_type;
 
804
  req->dip = usbdev->osdev->dip;
 
805
  req->pipe_handle = eph->pipe_handle;
 
806
 
 
807
  switch (xfer_type)
 
808
    {
 
809
    case UDI_USBXFER_ISO_READ:
 
810
      return req;
 
811
      break;
 
812
 
 
813
    case UDI_USBXFER_ISO_WRITE:
 
814
      return req;
 
815
      break;
 
816
 
 
817
    case UDI_USBXFER_BULK_READ:
 
818
      return req;
 
819
      break;
 
820
 
 
821
    case UDI_USBXFER_INTR_READ:
 
822
      return req;
 
823
      break;
 
824
 
 
825
    case UDI_USBXFER_BULK_WRITE:
 
826
      return req;
 
827
      break;
 
828
 
 
829
    default:
 
830
      cmn_err (CE_WARN, "Internal error - bad transfer type %d\n", xfer_type);
 
831
      KERNEL_FREE (req);
 
832
      return NULL;
 
833
    }
 
834
}
 
835
 
 
836
void
 
837
udi_usb_free_request (udi_usb_request_t * req)
 
838
{
 
839
  if (req == NULL)
 
840
    return;
 
841
 
 
842
  udi_usb_cancel_request (req);
 
843
 
 
844
  if (req->active)
 
845
    {
 
846
      cmn_err (CE_WARN, "Warning: Freeing active request\n");
 
847
    }
 
848
 
 
849
  switch (req->xfer_type)
 
850
    {
 
851
    case UDI_USBXFER_ISO_WRITE:
 
852
      req->isoc_req = NULL;
 
853
      break;
 
854
 
 
855
    case UDI_USBXFER_ISO_READ:
 
856
      req->isoc_req = NULL;
 
857
      break;
 
858
 
 
859
    case UDI_USBXFER_BULK_WRITE:
 
860
      req->bulk_req = NULL;
 
861
      break;
 
862
 
 
863
    case UDI_USBXFER_BULK_READ:
 
864
      req->bulk_req = NULL;
 
865
      break;
 
866
 
 
867
    case UDI_USBXFER_INTR_READ:
 
868
      req->intr_req = NULL;
 
869
      break;
 
870
 
 
871
    default:
 
872
      cmn_err (CE_WARN, "Internal error - bad transfer type %d\n",
 
873
               req->xfer_type);
 
874
    }
 
875
 
 
876
  KERNEL_FREE (req);
 
877
}
 
878
 
 
879
/*ARGSUSED*/
 
880
static void
 
881
isoc_play_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
 
882
{
 
883
  udi_usb_request_t *req =
 
884
    (udi_usb_request_t *) isoc_req->isoc_client_private;
 
885
 
 
886
  usb_free_isoc_req (isoc_req);
 
887
 
 
888
  req->isoc_req = NULL;
 
889
  req->active = 0;
 
890
 
 
891
  req->callback (req, req->callback_arg);
 
892
}
 
893
 
 
894
/*ARGSUSED*/
 
895
static void
 
896
isoc_rec_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
 
897
{
 
898
  int i;
 
899
  udi_usb_request_t *req =
 
900
    (udi_usb_request_t *) isoc_req->isoc_client_private;
 
901
 
 
902
  req->data = isoc_req->isoc_data;
 
903
 
 
904
  for (i = 0; i < isoc_req->isoc_pkts_count; i++)
 
905
    {
 
906
      int len;
 
907
 
 
908
      len = isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length;
 
909
 
 
910
      req->actlen = len;
 
911
 
 
912
      req->callback (req, req->callback_arg);
 
913
 
 
914
      req->data->b_rptr += len;
 
915
    }
 
916
 
 
917
  req->active = 0;
 
918
  usb_free_isoc_req (isoc_req);
 
919
}
 
920
 
 
921
/*ARGSUSED*/
 
922
static void
 
923
isoc_exc_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
 
924
{
 
925
  udi_usb_request_t *req =
 
926
    (udi_usb_request_t *) isoc_req->isoc_client_private;
 
927
  usb_cr_t reason;
 
928
 
 
929
  reason = isoc_req->isoc_completion_reason;
 
930
 
 
931
  usb_free_isoc_req (isoc_req);
 
932
  req->isoc_req = NULL;
 
933
  req->active = 0;
 
934
 
 
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));
 
938
}
 
939
 
 
940
/*ARGSUSED*/
 
941
void
 
942
bulk_play_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
 
943
{
 
944
  udi_usb_request_t *req =
 
945
    (udi_usb_request_t *) bulk_req->bulk_client_private;
 
946
 
 
947
  usb_free_bulk_req (bulk_req);
 
948
 
 
949
  req->bulk_req = NULL;
 
950
  req->active = 0;
 
951
 
 
952
  req->callback (req, req->callback_arg);
 
953
}
 
954
 
 
955
/*ARGSUSED*/
 
956
void
 
957
bulk_rec_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
 
958
{
 
959
  udi_usb_request_t *req =
 
960
    (udi_usb_request_t *) bulk_req->bulk_client_private;
 
961
 
 
962
  req->data = bulk_req->bulk_data;
 
963
  req->actlen = bulk_req->bulk_len;
 
964
  req->active = 0;
 
965
 
 
966
  req->callback (req, req->callback_arg);
 
967
  //usb_free_bulk_req (bulk_req);
 
968
}
 
969
 
 
970
/*ARGSUSED*/
 
971
static void
 
972
bulk_exc_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
 
973
{
 
974
  udi_usb_request_t *req =
 
975
    (udi_usb_request_t *) bulk_req->bulk_client_private;
 
976
  usb_cr_t reason;
 
977
 
 
978
  reason = bulk_req->bulk_completion_reason;
 
979
 
 
980
  usb_free_bulk_req (bulk_req);
 
981
  req->bulk_req = NULL;
 
982
  req->active = 0;
 
983
 
 
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));
 
987
}
 
988
 
 
989
/*ARGSUSED*/
 
990
void
 
991
intr_rec_callback (usb_pipe_handle_t ph, usb_intr_req_t * intr_req)
 
992
{
 
993
  udi_usb_request_t *req =
 
994
    (udi_usb_request_t *) intr_req->intr_client_private;
 
995
 
 
996
  req->data = intr_req->intr_data;
 
997
  req->actlen = intr_req->intr_len;
 
998
  req->active = 0;
 
999
 
 
1000
  req->callback (req, req->callback_arg);
 
1001
  //usb_free_intr_req (intr_req);
 
1002
}
 
1003
 
 
1004
/*ARGSUSED*/
 
1005
static void
 
1006
intr_exc_callback (usb_pipe_handle_t ph, usb_intr_req_t * intr_req)
 
1007
{
 
1008
  udi_usb_request_t *req =
 
1009
    (udi_usb_request_t *) intr_req->intr_client_private;
 
1010
  usb_cr_t reason;
 
1011
 
 
1012
  reason = intr_req->intr_completion_reason;
 
1013
 
 
1014
  usb_free_intr_req (intr_req);
 
1015
  req->intr_req = NULL;
 
1016
  req->active = 0;
 
1017
 
 
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));
 
1021
}
 
1022
 
 
1023
/*ARGSUSED*/
 
1024
int
 
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)
 
1029
{
 
1030
  int err;
 
1031
 
 
1032
  req->callback = callback;
 
1033
  req->callback_arg = callback_arg;
 
1034
 
 
1035
  if (req->active)
 
1036
    return 0;
 
1037
 
 
1038
  switch (xfer_type)
 
1039
    {
 
1040
    case UDI_USBXFER_ISO_WRITE:
 
1041
      {
 
1042
        usb_isoc_req_t *isoc_req;
 
1043
 
 
1044
        if (req->isoc_req != NULL)
 
1045
          isoc_req = req->isoc_req;
 
1046
        else
 
1047
          {
 
1048
            req->data = allocb (len, BPRI_HI);
 
1049
            if (req->data == NULL)
 
1050
              {
 
1051
                cmn_err (CE_WARN, "allocb_wait (isoc) failed\n");
 
1052
                KERNEL_FREE (req);
 
1053
                return OSS_ENOMEM;
 
1054
              }
 
1055
 
 
1056
            if ((isoc_req = usb_alloc_isoc_req (req->dip, 1, 0, 0)) == NULL)
 
1057
              {
 
1058
                cmn_err (CE_WARN, "usb_alloc_isoc_req failed\n");
 
1059
                freemsg (req->data);
 
1060
                KERNEL_FREE (req);
 
1061
                return OSS_ENOMEM;
 
1062
              }
 
1063
            req->isoc_req = isoc_req;
 
1064
          }
 
1065
 
 
1066
        if (isoc_req == NULL)
 
1067
          {
 
1068
            cmn_err (CE_WARN, "req->isoc==NULL\n");
 
1069
            return OSS_EIO;
 
1070
          }
 
1071
 
 
1072
        memcpy (req->data->b_wptr, data, len);
 
1073
        req->data->b_wptr += len;
 
1074
 
 
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;
 
1084
 
 
1085
        if ((err =
 
1086
             usb_pipe_isoc_xfer (req->pipe_handle, isoc_req,
 
1087
                                 0)) != USB_SUCCESS)
 
1088
          {
 
1089
            cmn_err (CE_WARN, "usb_pipe_isoc_xfer failed (%s)\n",
 
1090
                     usb_errstr (err));
 
1091
            return OSS_EIO;
 
1092
          }
 
1093
        req->active = 1;
 
1094
      }
 
1095
      break;
 
1096
 
 
1097
    case UDI_USBXFER_ISO_READ:
 
1098
      {
 
1099
        usb_isoc_req_t *isoc_req;
 
1100
 
 
1101
        if (req->isoc_req != NULL)
 
1102
          isoc_req = req->isoc_req;
 
1103
        else
 
1104
          {
 
1105
            if ((isoc_req =
 
1106
                 usb_alloc_isoc_req (req->dip, 1, len,
 
1107
                                     USB_FLAGS_SLEEP)) == NULL)
 
1108
              {
 
1109
                cmn_err (CE_WARN, "usb_alloc_isoc_req failed\n");
 
1110
                KERNEL_FREE (req);
 
1111
                return OSS_ENOMEM;
 
1112
              }
 
1113
            req->isoc_req = isoc_req;
 
1114
          }
 
1115
 
 
1116
        if (isoc_req == NULL)
 
1117
          {
 
1118
            cmn_err (CE_WARN, "req->isoc==NULL\n");
 
1119
            return OSS_EIO;
 
1120
          }
 
1121
 
 
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;
 
1129
        req->active = 1;
 
1130
 
 
1131
        if ((err =
 
1132
             usb_pipe_isoc_xfer (req->pipe_handle, isoc_req,
 
1133
                                 USB_FLAGS_NOSLEEP)) != USB_SUCCESS)
 
1134
          {
 
1135
            cmn_err (CE_WARN, "usb_pipe_isoc_xfer failed (%s)\n",
 
1136
                     usb_errstr (err));
 
1137
            return OSS_EIO;
 
1138
          }
 
1139
      }
 
1140
      break;
 
1141
 
 
1142
    case UDI_USBXFER_BULK_WRITE:
 
1143
      {
 
1144
        usb_bulk_req_t *bulk_req;
 
1145
 
 
1146
        if (req->bulk_req != NULL)
 
1147
          bulk_req = req->bulk_req;
 
1148
        else
 
1149
          {
 
1150
            req->data = allocb (len, BPRI_HI);
 
1151
            if (req->data == NULL)
 
1152
              {
 
1153
                cmn_err (CE_WARN, "allocb_wait (bulk) failed\n");
 
1154
                KERNEL_FREE (req);
 
1155
                return OSS_ENOMEM;
 
1156
              }
 
1157
 
 
1158
            if ((bulk_req = usb_alloc_bulk_req (req->dip, len, 0)) == NULL)
 
1159
              {
 
1160
                cmn_err (CE_WARN, "usb_alloc_bulk_req failed\n");
 
1161
                freemsg (req->data);
 
1162
                KERNEL_FREE (req);
 
1163
                return OSS_ENOMEM;
 
1164
              }
 
1165
            req->bulk_req = bulk_req;
 
1166
          }
 
1167
 
 
1168
        if (bulk_req == NULL)
 
1169
          {
 
1170
            cmn_err (CE_WARN, "req->bulk==NULL\n");
 
1171
            return OSS_EIO;
 
1172
          }
 
1173
 
 
1174
        memcpy (req->data->b_wptr, data, len);
 
1175
        req->data->b_wptr += len;
 
1176
 
 
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;
 
1184
 
 
1185
        if ((err =
 
1186
             usb_pipe_bulk_xfer (req->pipe_handle, bulk_req,
 
1187
                                 0)) != USB_SUCCESS)
 
1188
          {
 
1189
            cmn_err (CE_WARN, "usb_pipe_bulk_xfer failed (%s)\n",
 
1190
                     usb_errstr (err));
 
1191
            return OSS_EIO;
 
1192
          }
 
1193
        req->active = 1;
 
1194
      }
 
1195
      break;
 
1196
 
 
1197
    case UDI_USBXFER_BULK_READ:
 
1198
      {
 
1199
        usb_bulk_req_t *bulk_req;
 
1200
 
 
1201
        if (req->bulk_req != NULL)
 
1202
          bulk_req = req->bulk_req;
 
1203
        else
 
1204
          {
 
1205
#if 0
 
1206
            req->data = allocb (len, BPRI_HI);
 
1207
            if (req->data == NULL)
 
1208
              {
 
1209
                cmn_err (CE_WARN, "allocb_wait (bulk) failed\n");
 
1210
                KERNEL_FREE (req);
 
1211
                return OSS_ENOMEM;
 
1212
              }
 
1213
#endif
 
1214
 
 
1215
            if ((bulk_req =
 
1216
                 usb_alloc_bulk_req (req->dip, len, USB_FLAGS_SLEEP)) == NULL)
 
1217
              {
 
1218
                cmn_err (CE_WARN, "usb_alloc_bulk_req failed\n");
 
1219
                freemsg (req->data);
 
1220
                KERNEL_FREE (req);
 
1221
                return OSS_ENOMEM;
 
1222
              }
 
1223
            req->bulk_req = bulk_req;
 
1224
          }
 
1225
 
 
1226
        if (bulk_req == NULL)
 
1227
          {
 
1228
            cmn_err (CE_WARN, "req->bulk==NULL\n");
 
1229
            return OSS_EIO;
 
1230
          }
 
1231
 
 
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 */
 
1239
        req->active = 1;
 
1240
 
 
1241
        if ((err =
 
1242
             usb_pipe_bulk_xfer (req->pipe_handle, bulk_req,
 
1243
                                 USB_FLAGS_NOSLEEP)) != USB_SUCCESS)
 
1244
          {
 
1245
            cmn_err (CE_WARN, "usb_pipe_bulk_xfer failed (%s)\n",
 
1246
                     usb_errstr (err));
 
1247
            return OSS_EIO;
 
1248
          }
 
1249
      }
 
1250
      break;
 
1251
 
 
1252
    case UDI_USBXFER_INTR_READ:
 
1253
      {
 
1254
        usb_intr_req_t *intr_req;
 
1255
 
 
1256
        if (req->intr_req != NULL)
 
1257
          intr_req = req->intr_req;
 
1258
        else
 
1259
          {
 
1260
#if 0
 
1261
            req->data = allocb (len, BPRI_HI);
 
1262
            if (req->data == NULL)
 
1263
              {
 
1264
                cmn_err (CE_WARN, "allocb_wait (intr) failed\n");
 
1265
                KERNEL_FREE (req);
 
1266
                return OSS_ENOMEM;
 
1267
              }
 
1268
#endif
 
1269
 
 
1270
            if ((intr_req =
 
1271
                 usb_alloc_intr_req (req->dip, len, USB_FLAGS_SLEEP)) == NULL)
 
1272
              {
 
1273
                cmn_err (CE_WARN, "usb_alloc_intr_req failed\n");
 
1274
                freemsg (req->data);
 
1275
                KERNEL_FREE (req);
 
1276
                return OSS_ENOMEM;
 
1277
              }
 
1278
            req->intr_req = intr_req;
 
1279
          }
 
1280
 
 
1281
        if (intr_req == NULL)
 
1282
          {
 
1283
            cmn_err (CE_WARN, "req->intr==NULL\n");
 
1284
            return OSS_EIO;
 
1285
          }
 
1286
 
 
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 */
 
1295
        req->active = 1;
 
1296
 
 
1297
        if ((err =
 
1298
             usb_pipe_intr_xfer (req->pipe_handle, intr_req,
 
1299
                                 0)) != USB_SUCCESS)
 
1300
          {
 
1301
            cmn_err (CE_WARN, "usb_pipe_intr_xfer failed (%s)\n",
 
1302
                     usb_errstr (err));
 
1303
            return OSS_EIO;
 
1304
          }
 
1305
      }
 
1306
      break;
 
1307
 
 
1308
    default:
 
1309
      cmn_err (CE_WARN, "Unimplemented transfer type %d\n", xfer_type);
 
1310
      return OSS_EIO;
 
1311
    }
 
1312
 
 
1313
  return 0;
 
1314
}
 
1315
 
 
1316
int
 
1317
udi_usb_request_actlen (udi_usb_request_t * request)
 
1318
{
 
1319
  return request->actlen;
 
1320
}
 
1321
 
 
1322
unsigned char *
 
1323
udi_usb_request_actdata (udi_usb_request_t * request)
 
1324
{
 
1325
  return request->data->b_rptr;
 
1326
}
 
1327
 
 
1328
void
 
1329
udi_usb_cancel_request (udi_usb_request_t * req)
 
1330
{
 
1331
  if (req == NULL || !req->active)
 
1332
    return;
 
1333
 
 
1334
  req->active = 0;
 
1335
  usb_pipe_reset (req->dip, req->pipe_handle, USB_FLAGS_SLEEP, NULL, 0);
 
1336
 
 
1337
  switch (req->xfer_type)
 
1338
    {
 
1339
    case UDI_USBXFER_ISO_WRITE:
 
1340
      break;
 
1341
 
 
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;
 
1347
      break;
 
1348
 
 
1349
    case UDI_USBXFER_BULK_WRITE:
 
1350
      break;
 
1351
 
 
1352
    case UDI_USBXFER_BULK_READ:
 
1353
      req->bulk_req = NULL;
 
1354
      break;
 
1355
 
 
1356
    case UDI_USBXFER_INTR_READ:
 
1357
      req->intr_req = NULL;
 
1358
      break;
 
1359
 
 
1360
    default:
 
1361
      cmn_err (CE_WARN, "Internal error - bad transfer type %d\n",
 
1362
               req->xfer_type);
 
1363
    }
 
1364
}
 
1365
#endif