diff -uprN linux-2.6.12/drivers/usb/storage/Kconfig linux-2.6.12-working/drivers/usb/storage/Kconfig --- linux-2.6.12/drivers/usb/storage/Kconfig 2005-06-17 15:48:29.000000000 -0400 +++ linux-2.6.12-working/drivers/usb/storage/Kconfig 2005-08-18 18:22:54.000000000 -0400 @@ -111,3 +111,9 @@ config USB_STORAGE_JUMPSHOT Say Y here to include additional code to support the Lexar Jumpshot USB CompactFlash reader. +config USB_STORAGE_KARMA + bool "Rio Karma MP3 player (EXPERIMENTAL)" + depends on USB_STORAGE && EXPERIMENTAL + help + Say Y here to include additional code to support the Rio Karma + digital music player as a mass storage device. diff -uprN linux-2.6.12/drivers/usb/storage/rio_karma.c linux-2.6.12-working/drivers/usb/storage/rio_karma.c diff -uprN -x '.*' linux-2.6.12/drivers/usb/storage/Makefile linux-2.6.12-working/drivers/usb/storage/Makefile --- linux-2.6.12/drivers/usb/storage/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux-2.6.12-working/drivers/usb/storage/Makefile 2005-08-18 08:19:15.000000000 -0400 @@ -18,6 +18,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPC usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o +usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += rio_karma.o usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ initializers.o $(usb-storage-obj-y) --- linux-2.6.12/drivers/usb/storage/rio_karma.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.12-working/drivers/usb/storage/rio_karma.c 2005-08-24 08:38:13.000000000 -0400 @@ -0,0 +1,103 @@ +/* USB driver for DNNA Rio Karma + * + * Rio Karma driver v0.1.1 + * (C) 2005 Bob Copeland (email@bobcopeland.com) + * + * The Karma is a mass storage device, although it requires some + * initialization code to get in that mode. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include "rio_karma.h" +#include "usb.h" +#include "transport.h" +#include "debug.h" + +#define RIOP_INIT "RIOP\x00\x01\x08" +#define CMD_LEN 40 +#define RECV_LEN 0x200 + +/* Initialize the karma and get it into mass storage mode. + * + * The initialization begins by sending 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; + static char init_cmd[] = RIOP_INIT; + char *cmd, *recv, *buf; + unsigned long timeout = jiffies + 2 * HZ; /* give it a few seconds */ + + if (!(buf = kmalloc(CMD_LEN + RECV_LEN, GFP_KERNEL | __GFP_DMA))) + goto init_failed; + + cmd = buf; + recv = buf + CMD_LEN; + + US_DEBUGP("Initializing Karma...\n"); + + memcpy(cmd, init_cmd, sizeof(init_cmd)); + memset(&cmd[sizeof(init_cmd)], 0, CMD_LEN - sizeof(init_cmd)); + + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, cmd, + CMD_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + recv, RECV_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + cmd[4] = 0x80; + cmd[5] = 0; + for (;;) { + US_DEBUGP("Sending init command\n"); + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + cmd, CMD_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + recv, RECV_LEN, &partial); + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + if (recv[5] == 0x08) + break; + if (time_after(jiffies, timeout)) + goto init_failed; + msleep(10); + } + US_DEBUGP("Karma initialized.\n"); + kfree(buf); + return 0; + +init_failed: + kfree(buf); + US_DEBUGP("Could not initialize karma.\n"); + return USB_STOR_TRANSPORT_FAILED; +} + diff -uprN linux-2.6.12/drivers/usb/storage/rio_karma.h linux-2.6.12-working/drivers/usb/storage/rio_karma.h --- linux-2.6.12/drivers/usb/storage/rio_karma.h 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.12-working/drivers/usb/storage/rio_karma.h 2005-08-18 19:16:57.000000000 -0400 @@ -0,0 +1,31 @@ +/* Header file for USB driver for DNNA Rio Karma + * + * Rio Karma driver v0.1.1 + * + * (C) 2005 Bob Copeland (email@bobcopeland.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _RIO_KARMA_H +#define _RIO_KARMA_H + +#include +#include "usb.h" + +int rio_karma_init(struct us_data *); + +#endif diff -uprN linux-2.6.12/drivers/usb/storage/unusual_devs.h linux-2.6.12-working/drivers/usb/storage/unusual_devs.h --- linux-2.6.12/drivers/usb/storage/unusual_devs.h 2005-06-17 15:48:29.000000000 -0400 +++ linux-2.6.12-working/drivers/usb/storage/unusual_devs.h 2005-08-24 08:43:18.000000000 -0400 @@ -96,6 +96,14 @@ UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), #endif +#ifdef CONFIG_USB_STORAGE_KARMA +UNUSUAL_DEV( 0x045a, 0x5210, 0x0000, 0x9999, + "Rio", + "Rio Karma", + US_SC_SCSI, US_PR_BULK, rio_karma_init, + 0 ), +#endif + /* Patch submitted by Philipp Friedrich */ UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, "Kyocera", @@ -1039,3 +1047,4 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x US_SC_SCSI, US_PR_SDDR55, NULL, US_FL_SINGLE_LUN), #endif + diff -uprN linux-2.6.12/drivers/usb/storage/usb.c linux-2.6.12-working/drivers/usb/storage/usb.c --- linux-2.6.12/drivers/usb/storage/usb.c 2005-06-17 15:48:29.000000000 -0400 +++ linux-2.6.12-working/drivers/usb/storage/usb.c 2005-08-18 18:22:54.000000000 -0400 @@ -90,6 +90,9 @@ #ifdef CONFIG_USB_STORAGE_JUMPSHOT #include "jumpshot.h" #endif +#ifdef CONFIG_USB_STORAGE_KARMA +#include "rio_karma.h" +#endif /* Some informational data */