2 Copyright (C) 2006 by Michal Schulz
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include <aros/debug.h>
27 #include <exec/types.h>
30 #include <hidd/hidd.h>
33 #include <proto/oop.h>
34 #include <proto/utility.h>
39 /******************** Local utility functions area ********************/
41 static const char *unknown_name
= "? unknown name ?";
42 static const char *unknown_manufacturer
= "? unknown manufacturer ?";
43 static const char *unknown_serial
= "? unknown serial ?";
45 static BOOL
usb_SetAddress(OOP_Class
*cl
, OOP_Object
*o
, uint8_t address
)
47 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
50 USBDevice_Request request
= {
51 bmRequestType
: UT_WRITE_DEVICE
,
52 bRequest
: UR_SET_ADDRESS
,
53 wValue
: AROS_WORD2LE(address
),
54 wIndex
: AROS_WORD2LE(0),
55 wLength
: AROS_WORD2LE(0)
58 if (dev
->default_pipe
)
59 pipe
= dev
->default_pipe
;
61 pipe
= HIDD_USBDrv_CreatePipe(dev
->bus
, PIPE_Control
, dev
->fast
, dev
->address
, 0, 0, dev
->maxpacket
, 100);
63 BOOL ret
= HIDD_USBDrv_ControlTransfer(dev
->bus
, pipe
, &request
, NULL
, 0);
64 HIDD_USBDrv_DeletePipe(dev
->bus
, pipe
);
66 dev
->default_pipe
= NULL
;
70 D(bug("[USBDevice::New] testing address %d...\n", address
));
71 usb_device_descriptor_t descriptor
;
73 pipe
= HIDD_USBDrv_CreatePipe(dev
->bus
, PIPE_Control
, dev
->fast
, address
, 0, 0, dev
->maxpacket
, 100);
75 USBDevice_Request request
= {
76 bmRequestType
: UT_READ_DEVICE
,
77 bRequest
: UR_GET_DESCRIPTOR
,
78 wValue
: AROS_WORD2LE(UDESC_DEVICE
<< 8),
79 wIndex
: AROS_WORD2LE(0),
80 wLength
: AROS_WORD2LE(USB_DEVICE_DESCRIPTOR_SIZE
)
82 ret
= HIDD_USBDrv_ControlTransfer(dev
->bus
, pipe
, &request
, &descriptor
, sizeof(descriptor
));
86 D(bug("[USBDevice::New] New address set correctly\n"));
87 dev
->address
= address
;
88 dev
->default_pipe
= pipe
;
93 HIDD_USBDrv_DeletePipe(dev
->bus
, pipe
);
102 /******************** Implementation of interfaces ********************/
104 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, GetString
)
106 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
110 USBDevice_Request request
= {
111 bmRequestType
: UT_READ_DEVICE
,
112 bRequest
: UR_GET_DESCRIPTOR
,
113 wValue
: AROS_WORD2LE(UDESC_STRING
<< 8 | (msg
->id
& 0xff)),
114 wIndex
: AROS_WORD2LE(msg
->language
),
115 wLength
: AROS_WORD2LE(1)
118 if (HIDD_USBDevice_ControlMessage(o
, NULL
, &request
, msg
->string
, 1))
120 request
.wLength
= AROS_WORD2LE(msg
->string
->bLength
);
121 if (HIDD_USBDrv_ControlTransfer(dev
->bus
, dev
->default_pipe
, &request
, msg
->string
, msg
->string
->bLength
))
131 OOP_Object
*METHOD(USBDevice
, Root
, New
)
133 D(bug("[USB] USBDevice::New()\n"));
135 BASE(cl
->UserData
)->LibNode
.lib_OpenCnt
++;
137 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
140 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
141 usb_string_descriptor_t string
;
145 dev
->tr
= USBCreateTimer();
147 dev
->address
= GetTagData(aHidd_USBDevice_Address
, 0, msg
->attrList
);
148 dev
->hub
= (OOP_Object
*)GetTagData(aHidd_USBDevice_Hub
, 0, msg
->attrList
);
149 dev
->bus
= (OOP_Object
*)GetTagData(aHidd_USBDevice_Bus
, 0, msg
->attrList
);
150 dev
->fast
= GetTagData(aHidd_USBDevice_Fast
, TRUE
, msg
->attrList
);
151 dev
->maxpacket
= GetTagData(aHidd_USBDevice_MaxPacketSize
, 8, msg
->attrList
);
152 dev
->iface
= GetTagData(aHidd_USBDevice_Interface
, 0, msg
->attrList
);
153 dev
->default_pipe
= NULL
;
154 dev
->config
= USB_UNCONFIG_NO
;
155 dev
->next
= (OOP_Object
*)GetTagData(aHidd_USBDevice_Next
, 0, msg
->attrList
);
158 * The USB bus object not in attrList. Try to get it from itself, with help of GetAttr call.
159 * It sounds ridiculous, but it might happen that the GetAttr is overrided already (it is
160 * the case of HUB embedded in the driver
163 if (!dev
->bus
&& dev
->hub
)
164 OOP_GetAttr(dev
->hub
, aHidd_USBDevice_Bus
, (IPTR
*)&dev
->bus
);
166 D(bug("[USBDevice::New] Address=%02x, Interface=%02x, Bus=%p, Hub=%p\n", dev
->address
, dev
->iface
, dev
->bus
, dev
->hub
));
170 if (!dev
->default_pipe
)
172 dev
->default_pipe
= HIDD_USBDevice_CreatePipe(o
, PIPE_Control
, 0, 0, 0, 100);
175 /* Address was either unknown or equals zero. In such case the right address has
177 if (dev
->address
== 0)
179 D(bug("[USBDevice::New] fetching new device address\n"));
180 uint8_t addr
= HIDD_USB_AllocAddress(SD(cl
)->usb
, dev
->bus
);
181 D(bug("[USBDevice::New] trying address %d...\n", addr
));
182 if (!usb_SetAddress(cl
, o
, addr
))
183 HIDD_USB_FreeAddress(SD(cl
)->usb
, dev
->bus
, addr
);
186 /* Check whether the address is set now */
189 OOP_MethodID disp_mid
= OOP_GetMethodID((STRPTR
)IID_Root
, moRoot_Dispose
);
190 OOP_CoerceMethod(cl
, o
, &disp_mid
);
196 HIDD_USBDevice_GetDeviceDescriptor(o
, &dev
->descriptor
);
198 D(bug("[USBDevice::New] Device %04x:%04x %02x/%02x/%02x at address %08x:%02x\n",
199 AROS_LE2WORD(dev
->descriptor
.idProduct
), AROS_LE2WORD(dev
->descriptor
.idVendor
),
200 dev
->descriptor
.bDeviceClass
, dev
->descriptor
.bDeviceSubClass
, dev
->descriptor
.bDeviceProtocol
,
201 dev
->bus
, dev
->address
));
203 HIDD_USBDevice_GetString(o
, USB_LANGUAGE_TABLE
, 0, &string
);
204 D(bug("[USBDevice::New] Default LangID=%04x\n", string
.bString
[0]));
205 langid
= string
.bString
[0];
207 if (dev
->descriptor
.iProduct
&& HIDD_USBDevice_GetString(o
, dev
->descriptor
.iProduct
, langid
, &string
))
209 dev
->product_name
= AllocVecPooled(SD(cl
)->MemPool
, 1 + ((string
.bLength
- 2) >> 1));
211 for (i
=0; i
< (string
.bLength
- 2) >> 1; i
++) {
212 dev
->product_name
[i
] = AROS_LE2WORD(string
.bString
[i
]);
214 dev
->product_name
[(string
.bLength
- 2) >> 1] = 0;
216 D(bug("[USBDevice::New] iProduct = \"%s\"\n", dev
->product_name
));
219 dev
->product_name
= AllocVecPooled(SD(cl
)->MemPool
, 1 + strlen(unknown_name
));
220 CopyMem(unknown_name
, dev
->product_name
, strlen(unknown_name
) + 1);
223 if (dev
->descriptor
.iManufacturer
&& HIDD_USBDevice_GetString(o
, dev
->descriptor
.iManufacturer
, langid
, &string
))
225 dev
->manufacturer_name
= AllocVecPooled(SD(cl
)->MemPool
, 1 + ((string
.bLength
- 2) >> 1));
227 for (i
=0; i
< (string
.bLength
- 2) >> 1; i
++) {
228 dev
->manufacturer_name
[i
] = AROS_LE2WORD(string
.bString
[i
]);
230 dev
->manufacturer_name
[(string
.bLength
- 2) >> 1] = 0;
232 D(bug("[USBDevice::New] iManufacturer = \"%s\"\n", dev
->manufacturer_name
));
235 dev
->manufacturer_name
= AllocVecPooled(SD(cl
)->MemPool
, 1 + strlen(unknown_manufacturer
));
236 CopyMem(unknown_manufacturer
, dev
->manufacturer_name
, strlen(unknown_manufacturer
) + 1);
240 if (dev
->descriptor
.iSerialNumber
&& HIDD_USBDevice_GetString(o
, dev
->descriptor
.iSerialNumber
, langid
, &string
))
242 dev
->serialnumber_name
= AllocVecPooled(SD(cl
)->MemPool
, 1 + ((string
.bLength
- 2) >> 1));
244 for (i
=0; i
< (string
.bLength
- 2) >> 1; i
++) {
245 dev
->serialnumber_name
[i
] = AROS_LE2WORD(string
.bString
[i
]);
247 dev
->serialnumber_name
[(string
.bLength
- 2) >> 1] = 0;
249 D(bug("[USBDevice::New] iSerial = \"%s\"\n", dev
->serialnumber_name
));
252 dev
->serialnumber_name
= AllocVecPooled(SD(cl
)->MemPool
, 1 + strlen(unknown_serial
));
253 CopyMem(unknown_serial
, dev
->serialnumber_name
, strlen(unknown_serial
) + 1);
257 D(bug("[USB] USBDevice::New() = %p\n",o
));
260 BASE(cl
->UserData
)->LibNode
.lib_OpenCnt
--;
265 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, GetDescriptor
)
267 USBDevice_Request req
;
270 req
.bmRequestType
= UT_READ_DEVICE
;
271 req
.bRequest
= UR_GET_DESCRIPTOR
;
272 req
.wValue
= AROS_WORD2LE(msg
->type
<< 8 | msg
->index
);
273 req
.wIndex
= AROS_WORD2LE(0);
274 req
.wLength
= AROS_WORD2LE(msg
->length
);
276 ret
= HIDD_USBDevice_ControlMessage(o
, NULL
, &req
, msg
->descriptor
, msg
->length
);
281 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, GetConfigDescriptor
)
283 return HIDD_USBDevice_GetDescriptor(o
, UDESC_CONFIG
, msg
->index
, USB_CONFIG_DESCRIPTOR_SIZE
, msg
->descriptor
);
286 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, GetDeviceDescriptor
)
288 return HIDD_USBDevice_GetDescriptor(o
, UDESC_DEVICE
, 0, USB_DEVICE_DESCRIPTOR_SIZE
, msg
->descriptor
);
291 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, GetStatus
)
293 USBDevice_Request req
;
295 req
.bmRequestType
= UT_READ_DEVICE
;
296 req
.bRequest
= UR_GET_STATUS
;
297 req
.wValue
= AROS_WORD2LE(0);
298 req
.wIndex
= AROS_WORD2LE(0);
299 req
.wLength
= AROS_WORD2LE(sizeof(usb_status_t
));
301 return HIDD_USBDevice_ControlMessage(o
, NULL
, &req
, msg
->status
, sizeof(usb_status_t
));
305 void * METHOD(USBDevice
, Hidd_USBDevice
, CreatePipe
)
307 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
309 return HIDD_USBDrv_CreatePipe(dev
->bus
, msg
->type
, dev
->fast
, dev
->address
, msg
->endpoint
, msg
->period
, msg
->maxpacket
? msg
->maxpacket
: dev
->maxpacket
, msg
->timeout
);
312 void METHOD(USBDevice
, Hidd_USBDevice
, DeletePipe
)
314 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
316 HIDD_USBDrv_DeletePipe(dev
->bus
, msg
->pipe
);
319 void METHOD(USBDevice
, Hidd_USBDevice
, SetTimeout
)
321 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
323 HIDD_USBDrv_SetTimeout(dev
->bus
, msg
->pipe
? msg
->pipe
: dev
->default_pipe
, msg
->timeout
);
326 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, ControlMessage
)
328 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
329 APTR pipe
= msg
->pipe
? msg
->pipe
: dev
->default_pipe
;
331 return HIDD_USBDrv_ControlTransfer(dev
->bus
, pipe
, msg
->request
, msg
->buffer
, msg
->length
);
334 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, BulkTransfer
)
336 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
337 APTR pipe
= msg
->pipe
;
340 return HIDD_USBDrv_BulkTransfer(dev
->bus
, pipe
, msg
->buffer
, msg
->length
);
345 static BOOL
set_config(OOP_Object
*o
, int c
)
347 USBDevice_Request req
;
349 req
.bmRequestType
= UT_WRITE_DEVICE
;
350 req
.bRequest
= UR_SET_CONFIG
;
351 req
.wValue
= AROS_WORD2LE(c
);
352 req
.wIndex
= AROS_WORD2LE(0);
353 req
.wLength
= AROS_WORD2LE(0);
355 return HIDD_USBDevice_ControlMessage(o
, NULL
, &req
, NULL
, 0);
358 static usb_interface_descriptor_t
*find_idesc(usb_config_descriptor_t
*cd
, int ifaceidx
, int altidx
)
360 char *p
= (char *)cd
;
361 char *end
= p
+ AROS_LE2WORD(cd
->wTotalLength
);
362 usb_interface_descriptor_t
*d
;
363 int curidx
, lastidx
, curaidx
= 0;
365 for (curidx
= lastidx
= -1; p
< end
; ) {
366 d
= (usb_interface_descriptor_t
*)p
;
367 D(bug("[USBDevice] find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
369 ifaceidx
, curidx
, altidx
, curaidx
,
370 d
->bLength
, d
->bDescriptorType
));
371 if (d
->bLength
== 0) /* bad descriptor */
374 if (p
<= end
&& d
->bDescriptorType
== UDESC_INTERFACE
) {
375 if (d
->bInterfaceNumber
!= lastidx
) {
376 lastidx
= d
->bInterfaceNumber
;
381 if (ifaceidx
== curidx
&& altidx
== curaidx
)
388 static inline usb_endpoint_descriptor_t
*find_edesc(usb_config_descriptor_t
*cd
, int ifaceidx
, int altidx
,
391 char *p
= (char *)cd
;
392 char *end
= p
+ AROS_WORD2LE(cd
->wTotalLength
);
393 usb_interface_descriptor_t
*d
;
394 usb_endpoint_descriptor_t
*e
;
397 d
= find_idesc(cd
, ifaceidx
, altidx
);
400 if (endptidx
>= d
->bNumEndpoints
) /* quick exit */
404 for (p
= (char *)d
+ d
->bLength
; p
< end
; ) {
405 e
= (usb_endpoint_descriptor_t
*)p
;
406 if (e
->bLength
== 0) /* bad descriptor */
409 if (p
<= end
&& e
->bDescriptorType
== UDESC_INTERFACE
)
411 if (p
<= end
&& e
->bDescriptorType
== UDESC_ENDPOINT
) {
413 if (curidx
== endptidx
)
421 static BOOL
fill_iface(OOP_Class
*cl
, OOP_Object
*o
, int ifaceidx
, int altidx
)
423 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
425 InterfaceData
*ifc
= &dev
->interfaces
[ifaceidx
];
426 usb_interface_descriptor_t
*idesc
;
429 D(bug("[USBDevice] fill_iface: ifaceidx=%d altidx=%d\n",
432 idesc
= find_idesc(dev
->config_desc
, ifaceidx
, altidx
);
436 ifc
->interface
= idesc
;
437 ifc
->index
= ifaceidx
;
438 ifc
->altindex
= altidx
;
440 nendpt
= ifc
->interface
->bNumEndpoints
;
442 D(bug("[USBDevice] fill_iface: found idesc nendpt=%d\n", nendpt
));
446 ifc
->endpoints
= AllocVecPooled(SD(cl
)->MemPool
, nendpt
* sizeof(EndpointData
));
447 if (ifc
->endpoints
== NULL
)
450 ifc
->endpoints
= NULL
;
452 p
= (char *)ifc
->interface
+ ifc
->interface
->bLength
;
453 end
= (char *)dev
->config_desc
+ AROS_LE2WORD(dev
->config_desc
->wTotalLength
);
454 #define ed ((usb_endpoint_descriptor_t *)p)
456 for (endpt
= 0; endpt
< nendpt
; endpt
++)
458 D(bug("[USBDevice] fill_iface: endpt=%d\n", endpt
));
459 for (; p
< end
; p
+= ed
->bLength
) {
460 D(bug("[USBDevice] fill_iface: p=%p end=%p "
462 p
, end
, ed
->bLength
, ed
->bDescriptorType
));
463 if (p
+ ed
->bLength
<= end
&& ed
->bLength
!= 0 &&
464 ed
->bDescriptorType
== UDESC_ENDPOINT
)
466 if (ed
->bLength
== 0 ||
467 ed
->bDescriptorType
== UDESC_INTERFACE
)
470 /* passed end, or bad desc */
471 bug("[USBDevice] fill_iface: bad descriptor(s): %s\n",
472 ed
->bLength
== 0 ? "0 length" :
473 ed
->bDescriptorType
== UDESC_INTERFACE
? "iface desc":"out of data");
476 D(bug("[USBDevice] fill_iface: endpoint descriptor %p\n", ed
));
477 ifc
->endpoints
[endpt
].endpoint
= ed
;
483 if (ifc
->endpoints
!= NULL
) {
484 FreeVecPooled(SD(cl
)->MemPool
, ifc
->endpoints
);
485 ifc
->endpoints
= NULL
;
490 static void free_iface(OOP_Class
*cl
, OOP_Object
*o
, int i
)
492 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
493 InterfaceData
*iface
= &dev
->interfaces
[i
];
494 if (iface
->endpoints
)
495 FreeVecPooled(SD(cl
)->MemPool
, iface
->endpoints
);
498 BOOL
METHOD(USBDevice
, Hidd_USBDevice
, Configure
)
500 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
501 usb_config_descriptor_t cd
, *cdp
;
505 D(bug("[USBDevice::Configure] Configure(%d)\n", msg
->configNr
));
507 if (dev
->config
!= USB_UNCONFIG_NO
)
509 int i
, ifaces
= dev
->config_desc
->bNumInterface
;
510 for (i
=0; i
< ifaces
; i
++)
511 free_iface(cl
, o
, i
);
512 FreeVecPooled(SD(cl
)->MemPool
, dev
->interfaces
);
513 FreeVecPooled(SD(cl
)->MemPool
, dev
->config_desc
);
514 dev
->interfaces
= NULL
;
515 dev
->config_desc
= NULL
;
516 dev
->config
= USB_UNCONFIG_NO
;
519 if (msg
->configNr
== USB_UNCONFIG_INDEX
)
521 D(bug("[USBDevice::Configure] Unconfiguring "));
522 if ((err
= set_config(o
, USB_UNCONFIG_NO
)))
523 D(bug("with success\n"));
525 D(bug("with ERROR\n"));
529 HIDD_USBDevice_GetConfigDescriptor(o
, 0, &cd
);
530 length
= AROS_LE2WORD(cd
.wTotalLength
);
532 D(bug("[USBDevice::Configure] Fetching config descriptor of length %d\n", length
));
534 cdp
= AllocVecPooled(SD(cl
)->MemPool
, length
);
538 for (i
=0; i
< 3; i
++)
540 if (HIDD_USBDevice_GetDescriptor(o
, UDESC_CONFIG
, msg
->configNr
, length
, cdp
))
542 D(bug("[USBDevice::Configure] retry...\n"));
543 USBDelay(dev
->tr
, 200);
548 D(bug("[USBDevice::Configure] failed...\n"));
551 /* TODO: Power! Self powered? */
552 err
= set_config(o
, cdp
->bConfigurationValue
);
554 D(bug("[USBDevice::Configure] Allocating %d interfaces\n", cdp
->bNumInterface
));
555 dev
->interfaces
= AllocVecPooled(SD(cl
)->MemPool
, sizeof(InterfaceData
) * cdp
->bNumInterface
);
556 if (!dev
->interfaces
)
561 dev
->config_desc
= cdp
;
562 dev
->config
= cdp
->bConfigurationValue
;
564 for (i
= 0; i
< cdp
->bNumInterface
; i
++)
566 err
= fill_iface(cl
, o
, i
, 0);
569 D(bug("[USBDevice::Configure] error at interface %d\n", i
));
571 free_iface(cl
, o
, i
);
579 usb_interface_descriptor_t
* METHOD(USBDevice
, Hidd_USBDevice
, GetInterface
)
581 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
582 usb_interface_descriptor_t
*d
= NULL
;
584 if (dev
->config
!= USB_UNCONFIG_NO
)
586 if (msg
->interface
< dev
->config_desc
->bNumInterface
)
588 d
= dev
->interfaces
[msg
->interface
].interface
;
595 usb_endpoint_descriptor_t
* METHOD(USBDevice
, Hidd_USBDevice
, GetEndpoint
)
597 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
598 usb_endpoint_descriptor_t
*d
= NULL
;
600 if (dev
->config
!= USB_UNCONFIG_NO
)
602 if (msg
->interface
< dev
->config_desc
->bNumInterface
)
604 if (msg
->endpoint
< dev
->interfaces
[msg
->interface
].interface
->bNumEndpoints
)
606 d
= dev
->interfaces
[msg
->interface
].endpoints
[msg
->endpoint
].endpoint
;
611 DumpDescriptor((usb_descriptor_t
*)d
);
616 void METHOD(USBDevice
, Root
, Dispose
)
618 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
619 struct Library
*base
= &BASE(cl
->UserData
)->LibNode
;
621 D(bug("[USB] USBDevice::Dispose\n"));
624 OOP_DisposeObject(dev
->next
);
626 // Do not unconfigure. The device may not exist already...
627 // HIDD_USBDevice_Configure(o, USB_UNCONFIG_INDEX);
629 if (dev
->product_name
&& dev
->product_name
!= unknown_name
)
630 FreeVecPooled(SD(cl
)->MemPool
, dev
->product_name
);
632 if (dev
->manufacturer_name
&& dev
->manufacturer_name
!= unknown_manufacturer
)
633 FreeVecPooled(SD(cl
)->MemPool
, dev
->manufacturer_name
);
635 if (dev
->serialnumber_name
&& dev
->serialnumber_name
!= unknown_serial
)
636 FreeVecPooled(SD(cl
)->MemPool
, dev
->serialnumber_name
);
638 if (dev
->default_pipe
)
639 HIDD_USBDrv_DeletePipe(dev
->bus
, dev
->default_pipe
);
641 USBDeleteTimer(dev
->tr
);
643 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
648 void METHOD(USBDevice
, Root
, Get
)
651 DeviceData
*dev
= OOP_INST_DATA(cl
, o
);
653 if (IS_USBDEVICE_ATTR(msg
->attrID
, idx
))
657 case aoHidd_USBDevice_Address
:
658 *msg
->storage
= dev
->address
;
661 case aoHidd_USBDevice_Bus
:
662 *msg
->storage
= (intptr_t)dev
->bus
;
665 case aoHidd_USBDevice_Hub
:
666 *msg
->storage
= (intptr_t)dev
->hub
;
669 case aoHidd_USBDevice_Fast
:
670 *msg
->storage
= dev
->fast
;
673 case aoHidd_USBDevice_MaxPacketSize
:
674 *msg
->storage
= dev
->maxpacket
;
677 case aoHidd_USBDevice_ProductID
:
678 *msg
->storage
= AROS_LE2WORD(dev
->descriptor
.idProduct
);
681 case aoHidd_USBDevice_VendorID
:
682 *msg
->storage
= AROS_LE2WORD(dev
->descriptor
.idVendor
);
685 case aoHidd_USBDevice_ProductName
:
686 *msg
->storage
= (intptr_t)dev
->product_name
;
689 case aoHidd_USBDevice_ManufacturerName
:
690 *msg
->storage
= (intptr_t)dev
->manufacturer_name
;
693 case aoHidd_USBDevice_SerialNumber
:
694 *msg
->storage
= (intptr_t)dev
->serialnumber_name
;
697 case aoHidd_USBDevice_Next
:
698 *msg
->storage
= (intptr_t)dev
->next
;
701 case aoHidd_USBDevice_Interface
:
702 *msg
->storage
= (intptr_t)dev
->iface
;
705 case aoHidd_USBDevice_InterfaceNumber
:
706 *msg
->storage
= dev
->interfaces
[dev
->iface
].interface
->bInterfaceNumber
;
710 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
715 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
718 void METHOD(USBDevice
, Root
, Set
)
722 struct TagItem
*tags
= msg
->attrList
;
724 while ((tag
= NextTagItem(&tags
)))
726 if (IS_USBDEVICE_ATTR(tag
->ti_Tag
, idx
))
730 case aoHidd_USBDevice_Address
:
731 usb_SetAddress(cl
, o
, tag
->ti_Data
);
740 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
743 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);