blob: 4d0dba26ad749ff24ad5751873e6d5eeab96bcc6 [file] [log] [blame]
\ *****************************************************************************
\ * Copyright (c) 2004, 2008 IBM Corporation
\ * All rights reserved.
\ * This program and the accompanying materials
\ * are made available under the terms of the BSD License
\ * which accompanies this distribution, and is available at
\ * http://www.opensource.org/licenses/bsd-license.php
\ *
\ * Contributors:
\ * IBM Corporation - initial implementation
\ ****************************************************************************/
\ create the device tree for hub
: (hub-create) ( -- )
mps port-number new-device-address port-number
( mps port-number usb-address port-number )
new-device set-space ( mps port-number usb-address )
encode-int s" USB-ADDRESS" property ( mps port-number )
s" Address Set" usb-debug-print
encode-int s" reg" property ( mps )
s" Port Number Set" usb-debug-print
encode-int s" MPS-DCP" property
s" MPS Set" usb-debug-print
s" usb-hub.fs" INCLUDED
finish-device
;
\ encode properties for scsi or atapi device
: (atapi-scsi-property-set) ( -- )
dd-buffer @ e + c@ ( Manuf )
dd-buffer @ f + c@ ( Manuf Prod )
dd-buffer @ 10 + c@ ( Manuf Prod Serial-Num )
cd-buffer @ 16 + w@-le ( Manuf Prod Serial-Num ep-mps )
cd-buffer @ 14 + c@ ( Manuf Prod Serial-Num ep-mps ep-addr )
cd-buffer @ 1d + w@-le ( Manuf Prod Serial-Num ep-mps ep-addr ep-mps )
cd-buffer @ 1b + c@ ( Manuf Prod Serial-Num ep-mps ep-addr ep-mps ep-addr )
mps port-number new-device-address port-number
( Manuf Prod Serial-Num ep-mps ep-addr ep-mps ep-addr
mps port-num usb-addr port-num )
new-device set-space
( Manuf Prod Serial-Num ep-mps ep-addr ep-mps ep-addr
mps port-num usb-addr )
encode-int s" USB-ADDRESS" property
( Manuf Prod Serial-Num ep-mps ep-addr ep-mps ep-addr
mps port-num )
encode-int s" reg" property
( Manuf Prod Serial-Num ep-mps ep-addr ep-mps ep-addr
mps )
encode-int s" MPS-DCP" property
( Manuf Prod Serial-Num ep-mps ep-addr ep-mps ep-addr )
2 0 DO
dup 80 and IF
7f and encode-int
s" BULK-IN-EP-ADDR" property
encode-int s" MPS-BULKIN" property
ELSE
encode-int s" BULK-OUT-EP-ADDR" property
encode-int s" MPS-BULKOUT" property
THEN
LOOP ( Manuf Prod Serial-Num )
encode-int s" iSerialNumber" property ( Manuf Prod )
encode-int s" iProduct" property ( Manuf )
encode-int s" iManufacturer" property
;
\ To classify device as hub/atapi/scsi/HID device
: (device-classify)
( -- Interface-protocol Interface-subclass Interface-class TRUE|FALSE )
cd-buffer @ BULK-CONFIG-DESCRIPTOR-LEN erase
cd-buffer @ BULK-CONFIG-DESCRIPTOR-LEN mps new-device-address
( buffer descp-len mps usb-address )
control-std-get-configuration-descriptor
IF
cd-buffer @ 1+ c@ ( Descriptor-type )
2 = IF
cd-buffer @ 10 + c@ ( protocol )
cd-buffer @ f + c@ ( protocol subclass )
cd-buffer @ e + c@ ( protocol subclass class )
TRUE
ELSE
s" Not a valid configuration descriptor!!" usb-debug-print
FALSE
THEN
ELSE
s" Unable to read configuration descriptor!!" usb-debug-print
FALSE
THEN
;
\ create device tree for Atapi SFF-8020 device
: (atapi-8020-create) ( -- )
(atapi-scsi-property-set)
s" usb-storage.fs" INCLUDED
finish-device
;
\ create device tree for Atapi SFF-8070 device
: (atapi-8070-create) ( -- )
(atapi-scsi-property-set)
s" usb-storage.fs" INCLUDED
\ s" storage" device-name
finish-device
;
\ create device tree for SCSI device
: (scsi-create) ( -- )
s" SCSI-CREATE " usb-debug-print
\ ***********************************************************************
\ a problem was encountered on Media-Tray (REV-0):
\ The CDROM is connected to USB via an ATA/USB-Bridge (U38: CYPRESS CY7C68300)
\ The C-Revision of this chip has an malfunction which results in a
\ hanging IORD Signal at the ATA-Interface and so prevents from reading.
\ The B-Revision doesn't have this problem (populated on Media-Tray REV-5)
\ Two additional Mass-Storage-Resets are necessary to reset the ATA-Interface.
\ (see CYPRESS Application Notes to CY7C68300)
\ (see USB-Spec: 'Bulk-Only-Transport')
\ ***********************************************************************
\ a mounted ISO image (via USB) doesn't accept this bulk-reset-command!
\ ***********************************************************************
dd-buffer @ 8 + w@-le 4b4 = \ VendorID = CYPRESS ?
IF
dd-buffer @ a + w@-le 6830 = \ Device = CY7C68300 ?
IF
\ here a Cypress ATA/USB Bridge is detected
d# 20 ms
mps new-device-address 0 0 0 ( MPS fun-addr dir data-buff data-len )
control-bulk-reset ( TRUE|FALSE )
d# 100 ms
mps new-device-address 0 0 0 ( TRUE|FALSE MPS fun-addr dir data-buff data-len )
control-bulk-reset ( TRUE|FALSE TRUE|FALSE )
and invert
IF
." ** BULK-RESET failed **" cr
THEN
d# 20 ms
THEN
THEN
0 ch-buffer c! \ preset a clean response
mps new-device-address 0 ch-buffer 1 control-std-get-maxlun ( TRUE|FALSE )
IF
\ s" GET-MAX-LUN IS WORKING :" usb-debug-print
\ ch-buffer 1 dump cr \ dump the responsed message
ELSE
s" ERROR in GET-MAX-LUN " usb-debug-print
0 ch-buffer c! \ clear invalid numbers
cd-buffer @ 5 + c@ to temp1
temp1 new-device-address control-std-set-configuration drop
THEN
\ FIXME: an IBM external HDD reported a number of 127 LUNs which could
\ not be set up. We need to understand how to set up the device
\ to report the correct number of LUNs.
\ The USB Massbulk Standard 1.0 defines a maximum of 15 mult. LUNs.
\ Workaround: Devices that might report a higher number are treated
\ as having exactly one LUN. Without this workaround the
\ USB scan hangs during the setup of non-available LUNs.
\
\ Concerns: "FUJITSU MHV2040AT" (VendorID: 0x984 / DeviceID: 0x70)
\
\ MR: This Device reports an invalid MaxLUN number within the first
\ three seconds after power-on or USB-Reset. The following loop repeats
\ the MaxLUN request up to 8 times until a valid ( <15 ) value is responded.
\ This can last up to four seconds as there is a delay of 500ms in every loop
0 ( counter )
begin
dup 8 < ( counter flag ) \ max 8 * 500 ms
ch-buffer c@ f > ( counter flag flag ) \ is MuxLUN above limit ?
AND ( counter flag )
while
d# 500 ms \ this device is not yet ready
0 ch-buffer c! \ preset a clean response
mps new-device-address 0 ch-buffer 1 control-std-get-maxlun ( TRUE|FALSE )
not
IF
s" ** ERROR in GET-MAX-LUN ** " usb-debug-print
drop 10 \ replace counter to force loop end
THEN
1+ ( counter+1 )
repeat
drop
\ here is still the workaround to handle invalid MaxLUNs as '0'
\
ch-buffer c@ dup 0= swap f > or IF
s" + LUN: " ch-buffer c@ usb-debug-print-val
(atapi-scsi-property-set)
s" usb-storage.fs" INCLUDED
finish-device
ELSE
s" - LUN: " ch-buffer c@ usb-debug-print-val
(atapi-scsi-property-set)
s" usb-storage-wrapper.fs" INCLUDED
finish-device
THEN
;
\ Classify USB storage device by sub-class code
: (classify-storage) ( interface-protocol interface-subclass -- )
s" USB: Mass Storage Device Found!" usb-debug-print
swap 50 <> IF
s" USB storage: Protocol is not 50." usb-debug-print
drop EXIT
THEN
( interface-subclass )
CASE
02 OF (atapi-8020-create) s" ATAPI Interface " usb-debug-print ENDOF
05 OF (atapi-8070-create) s" ATAPI Interface " usb-debug-print ENDOF
06 OF (scsi-create) s" SCSI Interface " usb-debug-print ENDOF
dup OF s" USB storage: Unsupported sub-class code." usb-debug-print ENDOF
ENDCASE
;
\ create keyboard device tree
: (keyboard-create) ( -- )
cd-buffer @ 1f + c@ ( ep-mps )
cd-buffer @ 1d + c@ ( ep-mps ep-addr )
mps port-number new-device-address port-number
( ep-mps ep-addr mps port-num usb-addr port-num )
new-device set-space ( ep-mps ep-addr mps port-num usb-addr )
encode-int s" USB-ADDRESS" property ( ep-mps ep-addr mps port-num )
encode-int s" reg" property ( ep-mps ep-addr mps )
encode-int s" MPS-DCP" property ( ep-mps ep-addr )
7f and encode-int s" INT-IN-EP-ADDR" property
encode-int s" MPS-INTIN" property
new-device-address \ device-speed
s" usb-keyboard.fs" INCLUDED
finish-device
;
: (mouse-create) ( -- )
mps port-number new-device-address port-number
( mps port-num usb-addr port-num )
new-device set-space ( mps port-num usb-addr )
encode-int s" USB-ADDRESS" property ( mps port-num )
encode-int s" reg" property ( mps )
encode-int s" MPS-DCP" property
s" usb-mouse.fs" INCLUDED
finish-device
;
\ Classify by interface class code
: (classify-by-interface) ( -- )
(device-classify) IF
( Interface-protocol Interface-subclass Interface-class )
CASE
08 OF
( Interface-protocol Interface-subclass )
(classify-storage)
ENDOF
03 OF
( Interface-protocol Interface-subclass )
s" USB: HID Found!" usb-debug-print
01 = IF
case
01 of
s" USB keyboard!" usb-debug-print
(keyboard-create)
endof
02 of
s" USB mouse!" usb-debug-print
(mouse-create)
endof
dup of
s" USB: unsupported HID!" usb-debug-print
endof
endcase
ELSE
s" USB: unsupported HID protocol " rot usb-debug-print-val
THEN
ENDOF
dup OF
( Interface-protocol Interface-subclass )
s" USB: unsupported interface type." usb-debug-print
2drop
ENDOF
ENDCASE
THEN
;
\ create usb device tree depending upon classification of the device
\ after encoding apt properties
: create-usb-device-tree ( -- )
dd-buffer @ DEVICE-DESCRIPTOR-DEVCLASS-OFFSET + c@ ( Device-class )
CASE
HUB-DEVICE-CLASS OF s" USB: HUB found" usb-debug-print
(hub-create)
ENDOF
NO-CLASS OF
\ In this case, the INTERFACE descriptor
\ tells you whats what -- Refer USB spec.
(classify-by-interface)
ENDOF
DUP OF
s" USB: Unknown device found." usb-debug-print
ENDOF
ENDCASE
;