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 */

Reply via email to