This patch adds a block device for the Rio Karma. Not terribly useful at the moment because there is no FS driver. This is my first try at doing anything in the kernel and I know almost nothing about USB and SCSI other than what it took to figure this out, so be nice :) Please let me know if there is anything weird.
Read more at: http://bobcopeland.com/karma/ (Attached to keep gmail from wrapping the patch.) -Bob
diff -uprN linux-2.6.12/drivers/usb/storage/Kconfig linux-2.6.12-work/drivers/usb/storage/Kconfig --- linux-2.6.12/drivers/usb/storage/Kconfig 2005-06-17 15:48:29.000000000 -0400 +++ linux-2.6.12-work/drivers/usb/storage/Kconfig 2005-08-18 09:15:56.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/Makefile linux-2.6.12-work/drivers/usb/storage/Makefile --- linux-2.6.12/drivers/usb/storage/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux-2.6.12-work/drivers/usb/storage/Makefile 2005-08-18 09:15:56.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) diff -uprN linux-2.6.12/drivers/usb/storage/rio_karma.c linux-2.6.12-work/drivers/usb/storage/rio_karma.c --- linux-2.6.12/drivers/usb/storage/rio_karma.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.12-work/drivers/usb/storage/rio_karma.c 2005-08-18 12:37:08.000000000 -0400 @@ -0,0 +1,119 @@ +/* USB driver for DNNA Rio Karma + * + * Rio Karma driver v0.1 + * (C) 2005 Bob Copeland ([EMAIL PROTECTED]) + * + * 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 <linux/delay.h> +#include <linux/string.h> +#include <linux/jiffies.h> +#include "rio_karma.h" +#include "usb.h" +#include "transport.h" +#include "debug.h" + +#define RIOP_SIGN "RIOP" +#define CMD_LEN 40 +#define RESP_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; + + char cmd[CMD_LEN]; + char buf[RESP_LEN]; + + /* give it a few seconds to respond */ + unsigned long timeout = jiffies + 2 * HZ; + + US_DEBUGP("Initializing Karma...\n"); + + /* SINGLE_LUN flag is reset for Bulk devices - fix it */ + us->max_lun = 0; + + memset(cmd, 0, sizeof(cmd)); + memset(buf, 0, sizeof(buf)); + + strcpy(cmd, RIOP_SIGN); + cmd[5] = 1; + cmd[6] = 8; + + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, cmd, + sizeof(cmd), &partial); + + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + buf, sizeof(buf), &partial); + + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + for (;;) { + + memset(cmd, 0, sizeof(cmd)); + memset(buf, 0, sizeof(buf)); + + strcpy(cmd, RIOP_SIGN); + cmd[4] = 0x80; + cmd[6] = 0x08; + + US_DEBUGP("Sending init command\n"); + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + cmd, sizeof(cmd), &partial); + + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + buf, sizeof(buf), &partial); + + if (result != USB_STOR_XFER_GOOD) + goto init_failed; + + if (buf[5] == cmd[6]) { + US_DEBUGP("Karma initialized.\n"); + return 0; + } + + if (time_after(timeout, jiffies)) + break; + + msleep(10); + } + +init_failed: + 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-work/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-work/drivers/usb/storage/rio_karma.h 2005-08-18 10:14:50.000000000 -0400 @@ -0,0 +1,31 @@ +/* Header file for USB driver for DNNM Rio Karma + * + * Rio Karma driver v0.1 + * + * (C) 2005 Bob Copeland ([EMAIL PROTECTED]) + * + * 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 <linux/config.h> +#include "usb.h" + +int rio_karma_init(struct us_data *); + +#endif diff -uprN linux-2.6.12/drivers/usb/storage/.tmp_versions/usb-storage.mod linux-2.6.12-work/drivers/usb/storage/.tmp_versions/usb-storage.mod --- linux-2.6.12/drivers/usb/storage/.tmp_versions/usb-storage.mod 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.12-work/drivers/usb/storage/.tmp_versions/usb-storage.mod 2005-08-18 10:29:27.000000000 -0400 @@ -0,0 +1,2 @@ +drivers/usb/storage/usb-storage.ko +drivers/usb/storage/scsiglue.o drivers/usb/storage/protocol.o drivers/usb/storage/transport.o drivers/usb/storage/usb.o drivers/usb/storage/initializers.o drivers/usb/storage/sddr09.o drivers/usb/storage/sddr55.o drivers/usb/storage/freecom.o drivers/usb/storage/dpcm.o drivers/usb/storage/isd200.o drivers/usb/storage/datafab.o drivers/usb/storage/jumpshot.o drivers/usb/storage/rio_karma.o diff -uprN linux-2.6.12/drivers/usb/storage/unusual_devs.h linux-2.6.12-work/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-work/drivers/usb/storage/unusual_devs.h 2005-08-18 09:15:56.000000000 -0400 @@ -1039,3 +1039,12 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x US_SC_SCSI, US_PR_SDDR55, NULL, US_FL_SINGLE_LUN), #endif + +#ifdef CONFIG_USB_STORAGE_KARMA +UNUSUAL_DEV( 0x045a, 0x5210, 0x0000, 0x9999, + "Rio", + "Rio Karma", + US_SC_SCSI, US_PR_BULK, rio_karma_init, + US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN ), +#endif + diff -uprN linux-2.6.12/drivers/usb/storage/usb.c linux-2.6.12-work/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-work/drivers/usb/storage/usb.c 2005-08-18 09:15:56.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 */