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