diff options
author | Matthew Dharm <mdharm-usb@one-eyed-alien.net> | 2005-12-30 22:06:53 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-31 20:23:37 -0500 |
commit | abb02fdf83f981f2511b3772db6e106845c70ad9 (patch) | |
tree | 8106d93df3965f80914b30057c14cb3048c1098e /drivers/usb/storage | |
parent | 8e2ce4f92a0f34e8c3316ec58fd6eb6aa282448e (diff) |
[PATCH] USB: usb-storage: Add support for Rio Karma
This patch from Bob Copeland adds support for the Rio Karma portable
digital audio player to the usb-storage driver. The only thing needed to
support this device is a one-time (per plugin) init command which is sent
to the device.
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/initializers.c | 73 | ||||
-rw-r--r-- | drivers/usb/storage/initializers.h | 1 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 5 |
3 files changed, 79 insertions, 0 deletions
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 5b06f9240d05..ab173b30076e 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -45,6 +45,12 @@ | |||
45 | #include "debug.h" | 45 | #include "debug.h" |
46 | #include "transport.h" | 46 | #include "transport.h" |
47 | 47 | ||
48 | #define RIO_MSC 0x08 | ||
49 | #define RIOP_INIT "RIOP\x00\x01\x08" | ||
50 | #define RIOP_INIT_LEN 7 | ||
51 | #define RIO_SEND_LEN 40 | ||
52 | #define RIO_RECV_LEN 0x200 | ||
53 | |||
48 | /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target | 54 | /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target |
49 | * mode */ | 55 | * mode */ |
50 | int usb_stor_euscsi_init(struct us_data *us) | 56 | int usb_stor_euscsi_init(struct us_data *us) |
@@ -91,3 +97,70 @@ int usb_stor_ucr61s2b_init(struct us_data *us) | |||
91 | 97 | ||
92 | return (res ? -1 : 0); | 98 | return (res ? -1 : 0); |
93 | } | 99 | } |
100 | |||
101 | /* Place the Rio Karma into mass storage mode. | ||
102 | * | ||
103 | * The initialization begins by sending 40 bytes starting | ||
104 | * RIOP\x00\x01\x08\x00, which the device will ack with a 512-byte | ||
105 | * packet with the high four bits set and everything else null. | ||
106 | * | ||
107 | * Next, we send RIOP\x80\x00\x08\x00. Each time, a 512 byte response | ||
108 | * must be read, but we must loop until byte 5 in the response is 0x08, | ||
109 | * indicating success. */ | ||
110 | int rio_karma_init(struct us_data *us) | ||
111 | { | ||
112 | int result, partial; | ||
113 | char *recv; | ||
114 | unsigned long timeout; | ||
115 | |||
116 | // us->iobuf is big enough to hold cmd but not receive | ||
117 | if (!(recv = kmalloc(RIO_RECV_LEN, GFP_KERNEL))) | ||
118 | goto die_nomem; | ||
119 | |||
120 | US_DEBUGP("Initializing Karma...\n"); | ||
121 | |||
122 | memset(us->iobuf, 0, RIO_SEND_LEN); | ||
123 | memcpy(us->iobuf, RIOP_INIT, RIOP_INIT_LEN); | ||
124 | |||
125 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
126 | us->iobuf, RIO_SEND_LEN, &partial); | ||
127 | if (result != USB_STOR_XFER_GOOD) | ||
128 | goto die; | ||
129 | |||
130 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
131 | recv, RIO_RECV_LEN, &partial); | ||
132 | if (result != USB_STOR_XFER_GOOD) | ||
133 | goto die; | ||
134 | |||
135 | us->iobuf[4] = 0x80; | ||
136 | us->iobuf[5] = 0; | ||
137 | timeout = jiffies + msecs_to_jiffies(3000); | ||
138 | for (;;) { | ||
139 | US_DEBUGP("Sending init command\n"); | ||
140 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
141 | us->iobuf, RIO_SEND_LEN, &partial); | ||
142 | if (result != USB_STOR_XFER_GOOD) | ||
143 | goto die; | ||
144 | |||
145 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
146 | recv, RIO_RECV_LEN, &partial); | ||
147 | if (result != USB_STOR_XFER_GOOD) | ||
148 | goto die; | ||
149 | |||
150 | if (recv[5] == RIO_MSC) | ||
151 | break; | ||
152 | if (time_after(jiffies, timeout)) | ||
153 | goto die; | ||
154 | msleep(10); | ||
155 | } | ||
156 | US_DEBUGP("Karma initialized.\n"); | ||
157 | kfree(recv); | ||
158 | return 0; | ||
159 | |||
160 | die: | ||
161 | kfree(recv); | ||
162 | die_nomem: | ||
163 | US_DEBUGP("Could not initialize karma.\n"); | ||
164 | return USB_STOR_TRANSPORT_FAILED; | ||
165 | } | ||
166 | |||
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 4c1b2bd2e2e4..f9907a5cf129 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -48,3 +48,4 @@ int usb_stor_euscsi_init(struct us_data *us); | |||
48 | /* This function is required to activate all four slots on the UCR-61S2B | 48 | /* This function is required to activate all four slots on the UCR-61S2B |
49 | * flash reader */ | 49 | * flash reader */ |
50 | int usb_stor_ucr61s2b_init(struct us_data *us); | 50 | int usb_stor_ucr61s2b_init(struct us_data *us); |
51 | int rio_karma_init(struct us_data *us); | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index dc301e567cfc..5e2afd4a27bc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -145,6 +145,11 @@ UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, | |||
145 | US_SC_DEVICE, US_PR_BULK, NULL, | 145 | US_SC_DEVICE, US_PR_BULK, NULL, |
146 | US_FL_NEED_OVERRIDE ), | 146 | US_FL_NEED_OVERRIDE ), |
147 | 147 | ||
148 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, | ||
149 | "Rio", | ||
150 | "Rio Karma", | ||
151 | US_SC_SCSI, US_PR_BULK, rio_karma_init, 0), | ||
152 | |||
148 | /* Patch submitted by Philipp Friedrich <philipp@void.at> */ | 153 | /* Patch submitted by Philipp Friedrich <philipp@void.at> */ |
149 | UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, | 154 | UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, |
150 | "Kyocera", | 155 | "Kyocera", |