Skip to content

Commit

Permalink
[PATCH] USB: usb-storage: Add support for Rio Karma
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matthew Dharm authored and Greg Kroah-Hartman committed Feb 1, 2006
1 parent 8e2ce4f commit abb02fd
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
73 changes: 73 additions & 0 deletions drivers/usb/storage/initializers.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
#include "debug.h"
#include "transport.h"

#define RIO_MSC 0x08
#define RIOP_INIT "RIOP\x00\x01\x08"
#define RIOP_INIT_LEN 7
#define RIO_SEND_LEN 40
#define RIO_RECV_LEN 0x200

/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
* mode */
int usb_stor_euscsi_init(struct us_data *us)
Expand Down Expand Up @@ -91,3 +97,70 @@ int usb_stor_ucr61s2b_init(struct us_data *us)

return (res ? -1 : 0);
}

/* Place the Rio Karma into mass storage mode.
*
* The initialization begins by sending 40 bytes starting
* RIOP\x00\x01\x08\x00, which the device will ack with a 512-byte
* packet with the high four bits set and everything else null.
*
* Next, we send RIOP\x80\x00\x08\x00. Each time, a 512 byte response
* must be read, but we must loop until byte 5 in the response is 0x08,
* indicating success. */
int rio_karma_init(struct us_data *us)
{
int result, partial;
char *recv;
unsigned long timeout;

// us->iobuf is big enough to hold cmd but not receive
if (!(recv = kmalloc(RIO_RECV_LEN, GFP_KERNEL)))
goto die_nomem;

US_DEBUGP("Initializing Karma...\n");

memset(us->iobuf, 0, RIO_SEND_LEN);
memcpy(us->iobuf, RIOP_INIT, RIOP_INIT_LEN);

result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
us->iobuf, RIO_SEND_LEN, &partial);
if (result != USB_STOR_XFER_GOOD)
goto die;

result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
recv, RIO_RECV_LEN, &partial);
if (result != USB_STOR_XFER_GOOD)
goto die;

us->iobuf[4] = 0x80;
us->iobuf[5] = 0;
timeout = jiffies + msecs_to_jiffies(3000);
for (;;) {
US_DEBUGP("Sending init command\n");
result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
us->iobuf, RIO_SEND_LEN, &partial);
if (result != USB_STOR_XFER_GOOD)
goto die;

result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
recv, RIO_RECV_LEN, &partial);
if (result != USB_STOR_XFER_GOOD)
goto die;

if (recv[5] == RIO_MSC)
break;
if (time_after(jiffies, timeout))
goto die;
msleep(10);
}
US_DEBUGP("Karma initialized.\n");
kfree(recv);
return 0;

die:
kfree(recv);
die_nomem:
US_DEBUGP("Could not initialize karma.\n");
return USB_STOR_TRANSPORT_FAILED;
}

1 change: 1 addition & 0 deletions drivers/usb/storage/initializers.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ int usb_stor_euscsi_init(struct us_data *us);
/* This function is required to activate all four slots on the UCR-61S2B
* flash reader */
int usb_stor_ucr61s2b_init(struct us_data *us);
int rio_karma_init(struct us_data *us);
5 changes: 5 additions & 0 deletions drivers/usb/storage/unusual_devs.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_BULK, NULL,
US_FL_NEED_OVERRIDE ),

UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101,
"Rio",
"Rio Karma",
US_SC_SCSI, US_PR_BULK, rio_karma_init, 0),

/* Patch submitted by Philipp Friedrich <philipp@void.at> */
UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
"Kyocera",
Expand Down

0 comments on commit abb02fd

Please sign in to comment.