diff options
Diffstat (limited to 'linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch')
-rw-r--r-- | linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch | 3433 |
1 files changed, 0 insertions, 3433 deletions
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch deleted file mode 100644 index c9296cf224..0000000000 --- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch +++ /dev/null @@ -1,3433 +0,0 @@ -diff -Nur linux-2.4.18/drivers/usb/device/bi/sa1100.c linux-2.4.18-usb-storage/drivers/usb/device/bi/sa1100.c ---- linux-2.4.18/drivers/usb/device/bi/sa1100.c 2003-05-13 13:18:44.000000000 +0400 -+++ linux-2.4.18-usb-storage/drivers/usb/device/bi/sa1100.c 2004-03-01 07:20:38.000000000 +0300 -@@ -440,6 +440,7 @@ - udc_interrupts, *(UDCSR), *(UDCCS0), *(UDCAR)); - - usbd_device_event (udc_device, DEVICE_RESET, 0); -+ usbd_device_event (udc_device, DEVICE_ADDRESS_ASSIGNED,0); - } - - if (status & UDCSR_SUSIR) { -diff -Nur linux-2.4.18/drivers/usb/device/Config.in linux-2.4.18-usb-storage/drivers/usb/device/Config.in ---- linux-2.4.18/drivers/usb/device/Config.in 2003-05-13 13:18:45.000000000 +0400 -+++ linux-2.4.18-usb-storage/drivers/usb/device/Config.in 2003-11-07 05:35:14.000000000 +0300 -@@ -34,6 +34,7 @@ - comment 'USB Device functions' - source drivers/usb/device/net_fd/Config.in - source drivers/usb/device/serial_fd/Config.in -+ source drivers/usb/device/storage_fd/Config.in - - comment 'USB Device bus interfaces' - source drivers/usb/device/bi/Config.in -diff -Nur linux-2.4.18/drivers/usb/device/Makefile linux-2.4.18-usb-storage/drivers/usb/device/Makefile ---- linux-2.4.18/drivers/usb/device/Makefile 2003-05-13 13:18:45.000000000 +0400 -+++ linux-2.4.18-usb-storage/drivers/usb/device/Makefile 2003-11-07 05:35:01.000000000 +0300 -@@ -20,6 +20,7 @@ - - subdir-$(CONFIG_USBD_NET) += net_fd - subdir-$(CONFIG_USBD_SERIAL) += serial_fd -+subdir-$(CONFIG_USBD_STORAGE) += storage_fd - - #subdir-$(CONFIG_USBD_GENERIC_BUS) += gen_bi - #subdir-$(CONFIG_USBD_L7205_BUS) += l7205_bi -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/Config.help linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.help ---- linux-2.4.18/drivers/usb/device/storage_fd/Config.help 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.help 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,55 @@ -+CONFIG_USBD_STORAGE -+ Enable the generic mass storage function driver. This function is -+ used emulating a Linux block driver. -+ -+CONFIG_USBD_STORAGE_VENDORID -+ Optionally specify the mass storage USB Device Vendor ID. The top -+ level Vendor ID will be used if this is not specified. -+ -+CONFIG_USBD_STORAGE_PRODUCTID -+ Optionally specify the mass storage USB Device Product ID. The top -+ level Vendor ID will be used if this is not specified. -+ -+CONFIG_USBD_STORAGE_OUT_ENDPOINT -+ Specify the preferred OUT (received data) endpoint number. This is a -+ number from 0-15 and must be allowed by the bus interface device. -+ -+ Some devices such as the SA-1110 or L7205/L7210 may override this -+ value with a fixed value. -+ -+CONFIG_USBD_STORAGE_IN_ENDPOINT -+ Specify the preferred IN (transmit data) endpoint number. This is a -+ number from 0-15 and must be allowed by the bus interface device. -+ -+ Some devices such as the SA-1110 or L7205/L7210 may override this -+ value with a fixed value. -+ -+CONFIG_USBD_STORAGE_INT_ENDPOINT -+ Specify the preferred INT (interrupt) endpoint number. This is a -+ number from 0-15 and must be allowed by the bus interface device. -+ -+ Some devices such as the L7205/L7210 may override this value with a -+ fixed value. Others such as the SA-1110 do not allow an interrupt -+ value. -+ -+CONFIG_USBD_STORAGE_OUT_PKTSIZE -+ Specify the maximum packet size for the OUT endpoint. This allowable -+ values are normally 16, 32 and 64. -+ -+ Some devices such as the Linkup L7205/L7210 may override this value -+ with a lower maximum value (such as 32). -+ -+CONFIG_USBD_STORAGE_IN_PKTSIZE -+ Specify the maximum packet size for the IN endpoint. This allowable -+ values are normally 16, 32 and 64. -+ -+ Some devices such as the Linkup L7205/L7210 may override this value -+ with a lower maximum value (such as 32). -+ -+CONFIG_USBD_STORAGE_INT_PKTSIZE -+ Specify the maximum packet size for the INT endpoint. This allowable -+ values are normally 8 and 16. Some bus interface devices may not -+ support all values. -+ -+CONFIG_USBD_STORAGE_DEF_DEVICE_NAME -+ Specify the default block device name to used on mass storage. -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/Config.in linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.in ---- linux-2.4.18/drivers/usb/device/storage_fd/Config.in 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.in 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,29 @@ -+# -+# Generic Mass Storage Function Driver -+# -+# Copyright (c) 2003 Communication Technology Inc. -+# Copyright (C) 2001 Lineo, Inc. -+# Copyright (C) 2001 Hewlett-Packard Co. -+mainmenu_option next_comment -+comment "Mass Storage Function" -+ -+dep_tristate ' Mass Storage Function Driver' CONFIG_USBD_STORAGE $CONFIG_USBD -+if [ "$CONFIG_USBD_STORAGE" = "y" -o "$CONFIG_USBD_STORAGE" = "m" ]; then -+ hex ' Overide VendorID (hex value)' CONFIG_USBD_STORAGE_VENDORID "0000" -+ hex ' Overide ProductID (hex value)' CONFIG_USBD_STORAGE_PRODUCTID "0000" -+ -+ # allow setting of endpoint configurations for some architectures -+ int ' OUT Endpoint (0-15)' CONFIG_USBD_STORAGE_OUT_ENDPOINT "1" -+ int ' OUT PacketSize (16, 32, 64)' CONFIG_USBD_STORAGE_OUT_PKTSIZE "64" -+ int ' IN Endpoint (0-15)' CONFIG_USBD_STORAGE_IN_ENDPOINT "2" -+ int ' IN PacketSize (16, 32, 64)' CONFIG_USBD_STORAGE_IN_PKTSIZE "64" -+ -+ if [ ! "$CONFIG_ARCH_SA1100" = "y" -a ! "$CONFIG_ARCH_L7200" = "y" ]; then -+ int ' INT Endpoint (0-15)' CONFIG_USBD_STORAGE_INT_ENDPOINT "3" -+ int ' INT PacketSize (8, 16)' CONFIG_USBD_STORAGE_INT_PKTSIZE "16" -+ fi -+ -+ string ' Default Mass Storage device name' CONFIG_USBD_STORAGE_DEF_DEVICE_NAME "" -+fi -+ -+endmenu -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/Makefile linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Makefile ---- linux-2.4.18/drivers/usb/device/storage_fd/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Makefile 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,58 @@ -+# -+# SA1100 Function driver for a network USB Device -+# -+# Copyright (C) 2001 Lineo, Inc. -+# Copyright (C) 2001 Hewlett-Packard Co. -+ -+ -+O_TARGET := storage_fd_drv.o -+list-multi := storage_fd.o -+ -+storage_fd-objs := storage-fd.o storageproto.o schedule_task.o # netproto.o crc32.o -+ -+# Object file lists. -+ -+obj-y := -+obj-m := -+obj-n := -+obj- := -+ -+# Each configuration option enables a list of files. -+ -+obj-$(CONFIG_USBD_STORAGE) += storage_fd.o -+ -+# Extract lists of the multi-part drivers. -+# The 'int-*' lists are the intermediate files used to build the multi's. -+ -+multi-y := $(filter $(list-multi), $(obj-y)) -+multi-m := $(filter $(list-multi), $(obj-m)) -+int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) -+int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) -+ -+# Files that are both resident and modular: remove from modular. -+ -+obj-m := $(filter-out $(obj-y), $(obj-m)) -+int-m := $(filter-out $(int-y), $(int-m)) -+ -+# Translate to Rules.make lists. -+ -+O_OBJS := $(filter-out $(export-objs), $(obj-y)) -+OX_OBJS := $(filter $(export-objs), $(obj-y)) -+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) -+MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) -+MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) -+ -+# The global Rules.make. -+ -+include $(TOPDIR)/Rules.make -+ -+# Link rules for multi-part drivers. -+ -+storage_fd.o: $(storage_fd-objs) -+ $(LD) -r -o $@ $(storage_fd-objs) -+ -+# dependencies: -+ -+storage-fd.o: ../usbd.h ../usbd-bus.h ../usbd-func.h -+ -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.c linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.c ---- linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.c 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,230 @@ -+/* -+ * linux/drivers/usb/device/storage_fd/schedule_task.c - schedule task library -+ * -+ * Copyright (c) 2003 Lineo Solutions, Inc. -+ * -+ * Written by Shunnosuke kabata -+ * -+ * 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 of the License, 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 File -+******************************************************************************/ -+#include <linux/config.h> -+#include <linux/fs.h> -+#include <linux/string.h> -+#include <linux/mm.h> -+#include <linux/dcache.h> -+#include <linux/init.h> -+#include <linux/quotaops.h> -+#include <linux/slab.h> -+#include <linux/cache.h> -+#include <linux/swap.h> -+#include <linux/swapctl.h> -+#include <linux/prefetch.h> -+#include <linux/locks.h> -+#include <asm/uaccess.h> -+ -+#include "schedule_task.h" -+ -+/****************************************************************************** -+** Macro Define -+******************************************************************************/ -+#define TASK_DESC_NUM (512) -+ -+/****************************************************************************** -+** Structure Define -+******************************************************************************/ -+ -+/************************************** -+** TASK_DESC -+**************************************/ -+typedef struct _TASK_DESC{ -+ struct _TASK_DESC* next; -+ SCHEDULE_TASK_FUNC task_entry; -+ int task_param1; -+ int task_param2; -+ int task_param3; -+ int task_param4; -+ int task_param5; -+ char* file; -+ int line; -+} TASK_DESC; -+ -+/************************************** -+** OS_WRP_TASK_DATA -+**************************************/ -+typedef struct{ -+ volatile TASK_DESC* read_desc; -+ volatile TASK_DESC* write_desc; -+ TASK_DESC desc_pool[TASK_DESC_NUM]; -+ spinlock_t spin_lock; -+ struct tq_struct task_que; -+ unsigned long use_num; -+ unsigned long max_num; -+} TASK_DATA; -+ -+/****************************************************************************** -+** Variable Declaration -+******************************************************************************/ -+static TASK_DATA TaskData; -+ -+/****************************************************************************** -+** Local Function Prototype -+******************************************************************************/ -+static void task_entry(void*); -+ -+/****************************************************************************** -+** Global Function -+******************************************************************************/ -+void schedule_task_init(void) -+{ -+ int i; -+ -+ /* 0 clear */ -+ memset(&TaskData, 0x00, sizeof(TaskData)); -+ -+ /* Read/write pointer initialize */ -+ TaskData.read_desc = TaskData.write_desc = &TaskData.desc_pool[0]; -+ -+ /* Ling buffer initialize */ -+ for(i=0; i<(TASK_DESC_NUM-1); i++){ -+ TaskData.desc_pool[i].next = &TaskData.desc_pool[i+1]; -+ } -+ TaskData.desc_pool[i].next = &TaskData.desc_pool[0]; -+ -+ /* Spin lock initialize */ -+ spin_lock_init(&TaskData.spin_lock); -+ -+ /* Task queue initialize */ -+ PREPARE_TQUEUE(&TaskData.task_que, task_entry, &TaskData); -+ -+ return; -+} -+ -+int schedule_task_register(SCHEDULE_TASK_FUNC entry, int param1, int param2, -+ int param3, int param4, int param5) -+{ -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&TaskData.spin_lock, flags); -+ -+ /* Free descriptor check */ -+ if(TaskData.write_desc->next == TaskData.read_desc){ -+ printk(KERN_INFO "storage_fd: schedule task no descriptor.\n"); -+ spin_unlock_irqrestore(&TaskData.spin_lock, flags); -+ return -1; -+ } -+ -+ /* Descriptor set */ -+ TaskData.write_desc->task_entry = entry; -+ TaskData.write_desc->task_param1 = param1; -+ TaskData.write_desc->task_param2 = param2; -+ TaskData.write_desc->task_param3 = param3; -+ TaskData.write_desc->task_param4 = param4; -+ TaskData.write_desc->task_param5 = param5; -+ -+ /* Pointer update */ -+ TaskData.write_desc = TaskData.write_desc->next; -+ -+ /* Statistics set */ -+ TaskData.use_num++; -+ if(TaskData.use_num > TaskData.max_num){ -+ TaskData.max_num = TaskData.use_num; -+ } -+ -+ spin_unlock_irqrestore(&TaskData.spin_lock, flags); -+ -+ /* Task queue register */ -+ schedule_task(&TaskData.task_que); -+ -+ return 0; -+} -+ -+void schedule_task_all_unregister(void) -+{ -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&TaskData.spin_lock, flags); -+ TaskData.read_desc = TaskData.write_desc; -+ TaskData.use_num = 0; -+ spin_unlock_irqrestore(&TaskData.spin_lock, flags); -+} -+ -+ssize_t schedule_task_proc_read(struct file* file, char* buf, size_t count, -+ loff_t* pos) -+{ -+ char string[1024]; -+ int len = 0; -+ -+ len += sprintf(string + len, "Schedule task max num:0x%d\n", -+ TASK_DESC_NUM); -+ -+ len += sprintf(string + len, "Schedule task use num:0x%ld\n", -+ TaskData.use_num); -+ -+ len += sprintf(string + len, "Schedule task max use num:0x%ld\n", -+ TaskData.max_num); -+ -+ *pos += len; -+ if(len > count){ -+ len = -EINVAL; -+ } -+ else -+ if(len > 0 && copy_to_user(buf, string, len)) { -+ len = -EFAULT; -+ } -+ -+ return len; -+} -+ -+/****************************************************************************** -+** Local Function -+******************************************************************************/ -+static void task_entry(void* data) -+{ -+ int cond; -+ unsigned long flags = 0; -+ volatile TASK_DESC* desc; -+ -+ for(;;){ -+ -+ spin_lock_irqsave(&TaskData.spin_lock, flags); -+ desc = TaskData.read_desc; -+ cond = (TaskData.read_desc == TaskData.write_desc); -+ spin_unlock_irqrestore(&TaskData.spin_lock, flags); -+ -+ if(cond) break; -+ -+ /* Task call */ -+ desc->task_entry(desc->task_param1, desc->task_param2, -+ desc->task_param3, desc->task_param4, desc->task_param5); -+ -+ spin_lock_irqsave(&TaskData.spin_lock, flags); -+ -+ /* Pointer update */ -+ TaskData.read_desc = TaskData.read_desc->next; -+ -+ /* Statistics set */ -+ TaskData.use_num--; -+ -+ spin_unlock_irqrestore(&TaskData.spin_lock, flags); -+ } -+ -+ return; -+} -+ -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.h linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.h ---- linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.h 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,41 @@ -+/* -+ * linux/drivers/usb/device/storage_fd/schedule_task.h - schedule task library header -+ * -+ * Copyright (c) 2003 Lineo Solutions, Inc. -+ * -+ * Written by Shunnosuke kabata -+ * -+ * 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 of the License, 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 _SCHEDULE_TASK_H_ -+#define _SCHEDULE_TASK_H_ -+ -+/****************************************************************************** -+** Macro Define -+******************************************************************************/ -+typedef int (*SCHEDULE_TASK_FUNC)(int, int, int, int, int); -+ -+/****************************************************************************** -+** Global Function Prototype -+******************************************************************************/ -+void schedule_task_init(void); -+int schedule_task_register(SCHEDULE_TASK_FUNC, int, int, int, int, int); -+void schedule_task_all_unregister(void); -+ssize_t schedule_task_proc_read(struct file*, char*, size_t, loff_t*); -+ -+#endif /* _SCHEDULE_TASK_H_ */ -+ -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/storage-fd.c linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storage-fd.c ---- linux-2.4.18/drivers/usb/device/storage_fd/storage-fd.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storage-fd.c 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,865 @@ -+/* -+ * linux/drivers/usb/device/storage_fd/storage-fd.c - mass storage function driver -+ * -+ * Copyright (c) 2003 Lineo Solutions, Inc. -+ * -+ * Written by Shunnosuke kabata -+ * -+ * 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 of the License, 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. -+ * -+ * Based on -+ * -+ * linux/drivers/usbd/net_fd/net-fd.c - network function driver -+ * -+ * Copyright (c) 2000, 2001, 2002 Lineo -+ * Copyright (c) 2001 Hewlett Packard -+ * -+ * By: -+ * Stuart Lynne <sl@lineo.com>, -+ * Tom Rushworth <tbr@lineo.com>, -+ * Bruce Balden <balden@lineo.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 of the License, 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 File -+******************************************************************************/ -+#include <linux/config.h> -+#include <linux/module.h> -+ -+#include "../usbd-export.h" -+#include "../usbd-build.h" -+#include "../usbd-module.h" -+ -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/netdevice.h> -+#include <linux/skbuff.h> -+#include <linux/etherdevice.h> -+#include <linux/rtnetlink.h> -+#include <linux/smp_lock.h> -+#include <linux/ctype.h> -+#include <linux/timer.h> -+#include <linux/string.h> -+#include <linux/atmdev.h> -+#include <linux/pkt_sched.h> -+#include <linux/delay.h> -+#include <asm/uaccess.h> -+#include <asm/system.h> -+#include <net/arp.h> -+ -+#include <linux/autoconf.h> -+ -+#include "../usbd.h" -+#include "../usbd-func.h" -+#include "../usbd-bus.h" -+#include "../usbd-inline.h" -+#include "../usbd-arch.h" -+#include "../hotplug.h" -+ -+#include "schedule_task.h" -+#include "storageproto.h" -+ -+/****************************************************************************** -+** Macro Define -+******************************************************************************/ -+ -+/************************************** -+** Module Information -+**************************************/ -+ -+MODULE_AUTHOR("Shunnosuke kabata"); -+MODULE_DESCRIPTION("USB Device Mass Storage Function"); -+USBD_MODULE_INFO("storage_fd 0.1"); -+ -+/************************************** -+** Configration Check -+**************************************/ -+ -+#if !defined (CONFIG_USBD_VENDORID) && !defined(CONFIG_USBD_STORAGE_VENDORID) -+#error No Vendor ID -+#endif -+#if !defined (CONFIG_USBD_PRODUCTID) && !defined(CONFIG_USBD_STORAGE_PRODUCTID) -+#error No Product ID -+#endif -+ -+#if defined(CONFIG_USBD_STORAGE_VENDORID) && (CONFIG_USBD_STORAGE_VENDORID > 0) -+#undef CONFIG_USBD_VENDORID -+#define CONFIG_USBD_VENDORID CONFIG_USBD_STORAGE_VENDORID -+#endif -+ -+#if defined(CONFIG_USBD_STORAGE_PRODUCTID) && (CONFIG_USBD_STORAGE_PRODUCTID > 0) -+#undef CONFIG_USBD_PRODUCTID -+#define CONFIG_USBD_PRODUCTID CONFIG_USBD_STORAGE_PRODUCTID -+#endif -+ -+#ifndef CONFIG_USBD_MAXPOWER -+#define CONFIG_USBD_MAXPOWER 0 -+#endif -+ -+#ifndef CONFIG_USBD_MANUFACTURER -+#define CONFIG_USBD_MANUFACTURER "Sharp" -+#endif -+ -+#define MAXTRANSFER (512) -+ -+#ifndef CONFIG_USBD_VENDORID -+#error "CONFIG_USBD_VENDORID not defined" -+#endif -+ -+#ifndef CONFIG_USBD_PRODUCTID -+#error "CONFIG_USBD_PRODUCTID not defined" -+#endif -+ -+#ifndef CONFIG_USBD_PRODUCT_NAME -+#define CONFIG_USBD_PRODUCT_NAME "Linux Mass Storage Driver" -+#endif -+ -+#ifndef CONFIG_USBD_SERIAL_NUMBER_STR -+#define CONFIG_USBD_SERIAL_NUMBER_STR "" -+#endif -+ -+/* -+ * USB 2.0 spec does not mention it, but MaxPower is expected to be at least one -+ * and is tested for in USB configuration tests. -+ */ -+ -+#ifdef CONFIG_USBD_SELFPOWERED -+#define BMATTRIBUTE BMATTRIBUTE_RESERVED | BMATTRIBUTE_SELF_POWERED -+#define BMAXPOWER 1 -+#else -+#define BMATTRIBUTE BMATTRIBUTE_RESERVED -+#define BMAXPOWER CONFIG_USBD_MAXPOWER -+#endif -+ -+/* -+ * setup some default values for pktsizes and endpoint addresses. -+ */ -+ -+#ifndef CONFIG_USBD_STORAGE_OUT_PKTSIZE -+#define CONFIG_USBD_STORAGE_OUT_PKTSIZE 64 -+#endif -+ -+#ifndef CONFIG_USBD_STORAGE_IN_PKTSIZE -+#define CONFIG_USBD_STORAGE_IN_PKTSIZE 64 -+#endif -+ -+#ifndef CONFIG_USBD_STORAGE_INT_PKTSIZE -+#define CONFIG_USBD_STORAGE_INT_PKTSIZE 16 -+#endif -+ -+#ifndef CONFIG_USBD_STORAGE_OUT_ENDPOINT -+#define CONFIG_USBD_STORAGE_OUT_ENDPOINT 1 -+#endif -+ -+#ifndef CONFIG_USBD_STORAGE_IN_ENDPOINT -+#define CONFIG_USBD_STORAGE_IN_ENDPOINT 2 -+#endif -+ -+#ifndef CONFIG_USBD_STORAGE_INT_ENDPOINT -+#define CONFIG_USBD_STORAGE_INT_ENDPOINT 3 -+#endif -+ -+/* -+ * check for architecture specific endpoint configurations -+ */ -+ -+#if defined(ABS_OUT_ADDR) -+ //#warning -+ //#warning USING ABS ENDPOINT OUT ADDRESS -+ #undef CONFIG_USBD_STORAGE_OUT_ENDPOINT -+ -+ #if ABS_OUT_ADDR > 0 -+ #define CONFIG_USBD_STORAGE_OUT_ENDPOINT ABS_OUT_ADDR -+ #endif -+ -+#elif defined(MAX_OUT_ADDR) && defined(CONFIG_USBD_STORAGE_OUT_ENDPOINT) && (CONFIG_USBD_STORAGE_OUT_ENDPOINT > MAX_OUT_ADDR) -+ //#warning -+ //#warning USING DEFAULT ENDPOINT OUT ADDRESS -+ #undef CONFIG_USBD_STORAGE_OUT_ENDPOINT -+ #define CONFIG_USBD_STORAGE_OUT_ENDPOINT DFL_OUT_ADDR -+ -+#endif /* elif */ -+ -+#if defined(ABS_IN_ADDR) -+ //#warning -+ //#warning USING ABS ENDPOINT IN ADDRESS -+ #undef CONFIG_USBD_STORAGE_IN_ENDPOINT -+ -+ #if ABS_IN_ADDR > 0 -+ #define CONFIG_USBD_STORAGE_IN_ENDPOINT ABS_IN_ADDR -+ #endif -+ -+#elif defined(MAX_IN_ADDR) && defined(CONFIG_USBD_STORAGE_IN_ENDPOINT) && (CONFIG_USBD_STORAGE_IN_ENDPOINT > MAX_IN_ADDR) -+ //#warning -+ //#warning USING DEFAULT ENDPOINT IN ADDRESS -+ #undef CONFIG_USBD_STORAGE_IN_ENDPOINT -+ #define CONFIG_USBD_STORAGE_IN_ENDPOINT DFL_IN_ADDR -+ -+#endif /* elif */ -+ -+#if defined(ABS_INT_ADDR) -+ //#warning -+ //#warning USING ABS ENDPOINT INT ADDRESS -+ #undef CONFIG_USBD_STORAGE_INT_ENDPOINT -+ -+ #if ABS_INT_ADDR -+ #define CONFIG_USBD_STORAGE_INT_ENDPOINT ABS_INT_ADDR -+ #endif -+ -+#elif defined(MAX_INT_ADDR) && defined(CONFIG_USBD_STORAGE_INT_ENDPOINT) && (CONFIG_USBD_STORAGE_INT_ENDPOINT > MAX_INT_ADDR) -+ //#warning -+ //#warning USING DEFAULT ENDPOINT INT ADDRESS -+ #undef CONFIG_USBD_STORAGE_INT_ENDPOINT -+ #define CONFIG_USBD_STORAGE_INT_ENDPOINT DFL_INT_ADDR -+ -+#endif /* elif */ -+ -+#if defined(MAX_OUT_PKTSIZE) && defined(CONFIG_USBD_STORAGE_OUT_PKTSIZE) && CONFIG_USBD_STORAGE_OUT_PKTSIZE > MAX_OUT_PKTSIZE -+ //#warning -+ //#warning OVERIDING ENDPOINT OUT PKTSIZE -+ #undef CONFIG_USBD_STORAGE_OUT_PKTSIZE -+ #define CONFIG_USBD_STORAGE_OUT_PKTSIZE MAX_OUT_PKTSIZE -+#endif -+ -+#if defined(MAX_IN_PKTSIZE) && defined(CONFIG_USBD_STORAGE_IN_PKTSIZE) && CONFIG_USBD_STORAGE_IN_PKTSIZE > MAX_IN_PKTSIZE -+ //#warning -+ //#warning OVERIDING ENDPOINT IN PKTSIZE -+ #undef CONFIG_USBD_STORAGE_IN_PKTSIZE -+ #define CONFIG_USBD_STORAGE_IN_PKTSIZE MAX_IN_PKTSIZE -+#endif -+ -+#if defined(MAX_INT_PKTSIZE) && defined(CONFIG_USBD_STORAGE_INT_PKTSIZE) && CONFIG_USBD_STORAGE_INT_PKTSIZE > MAX_INT_PKTSIZE -+ //#warning -+ //#warning OVERIDING ENDPOINT INT PKTSIZE -+ #undef CONFIG_USBD_STORAGE_INT_PKTSIZE -+ #define CONFIG_USBD_STORAGE_INT_PKTSIZE MAX_INT_PKTSIZE -+#endif -+ -+/****************************************************************************** -+** Variable Declaration -+******************************************************************************/ -+ -+/************************************** -+** Module Parameters -+**************************************/ -+ -+static u32 vendor_id; -+static u32 product_id; -+static int out_pkt_sz = CONFIG_USBD_STORAGE_OUT_PKTSIZE; -+static int in_pkt_sz = CONFIG_USBD_STORAGE_IN_PKTSIZE; -+ -+MODULE_PARM(vendor_id, "i"); -+MODULE_PARM(product_id, "i"); -+MODULE_PARM(out_pkt_sz, "i"); -+MODULE_PARM(in_pkt_sz, "i"); -+ -+MODULE_PARM_DESC(vendor_id, "vendor id"); -+MODULE_PARM_DESC(product_id, "product id"); -+ -+/************************************** -+** Mass Storage Configuration -+**************************************/ -+ -+/* -+ * Data Interface Alternate 1 endpoints -+ */ -+static __initdata struct usb_endpoint_description StorageAlt1Endpoints[] = { -+ { -+ bEndpointAddress:CONFIG_USBD_STORAGE_OUT_ENDPOINT, -+ bmAttributes:BULK, -+ wMaxPacketSize:CONFIG_USBD_STORAGE_OUT_PKTSIZE, -+ bInterval:0, -+ direction:OUT, -+ transferSize:MAXTRANSFER, -+ }, -+ -+ { -+ bEndpointAddress:CONFIG_USBD_STORAGE_IN_ENDPOINT, -+ bmAttributes:BULK, -+ wMaxPacketSize:CONFIG_USBD_STORAGE_IN_PKTSIZE, -+ bInterval:0, -+ direction:IN, -+ transferSize:MAXTRANSFER, -+ }, -+ -+#if defined(CONFIG_USBD_STORAGE_INT_ENDPOINT) && (CONFIG_USBD_STORAGE_INT_ENDPOINT > 0) -+ { -+ bEndpointAddress:CONFIG_USBD_STORAGE_INT_ENDPOINT, -+ bmAttributes:INTERRUPT, -+ wMaxPacketSize:CONFIG_USBD_STORAGE_INT_PKTSIZE, -+ bInterval:10, -+ direction:IN, -+ transferSize:CONFIG_USBD_STORAGE_INT_PKTSIZE, -+ }, -+#endif -+}; -+ -+ -+/* -+ * Data Interface Alternate description(s) -+ */ -+static __initdata struct usb_alternate_description StorageAlternateDescriptions[] = { -+ { -+ #if defined(CONFIG_USBD_STORAGE_NO_STRINGS) -+ iInterface:"", -+ #else -+ iInterface:"Mass Storage Interface", -+ #endif -+ bAlternateSetting:0, -+ classes:0, -+ class_list:NULL, -+ endpoints:sizeof (StorageAlt1Endpoints) / sizeof (struct usb_endpoint_description), -+ endpoint_list:StorageAlt1Endpoints, -+ }, -+}; -+ -+/* -+ * Interface description(s) -+ */ -+static __initdata struct usb_interface_description StorageInterfaces[] = { -+ { -+ #if defined(CONFIG_USBD_STORAGE_NO_STRINGS) -+ iInterface:"", -+ #else -+ iInterface:"Mass Storage Interface", -+ #endif -+ bInterfaceClass:MASS_STORAGE_CLASS, -+ bInterfaceSubClass:MASS_STORAGE_SUBCLASS_SCSI, -+ bInterfaceProtocol:MASS_STORAGE_PROTO_BULK_ONLY, -+ alternates:sizeof (StorageAlternateDescriptions) / sizeof (struct usb_alternate_description), -+ alternate_list:StorageAlternateDescriptions, -+ }, -+}; -+ -+/****************************************************************************** -+** USB Configuration -+******************************************************************************/ -+ -+/* -+ * Configuration description(s) -+ */ -+struct __initdata usb_configuration_description StorageDescription[] = { -+ { -+ #if defined(CONFIG_USBD_STORAGE_NO_STRINGS) -+ iConfiguration:"", -+ #else -+ iConfiguration:"Mass Storage Configuration", -+ #endif -+ bmAttributes:BMATTRIBUTE, -+ bMaxPower:BMAXPOWER, -+ interfaces:sizeof (StorageInterfaces) / sizeof (struct usb_interface_description), -+ interface_list:StorageInterfaces, -+ }, -+}; -+ -+/* -+ * Device Description -+ */ -+struct __initdata usb_device_description StorageDeviceDescription = { -+ bDeviceClass:0, -+ bDeviceSubClass:0, // XXX -+ bDeviceProtocol:0, // XXX -+ idVendor:CONFIG_USBD_VENDORID, -+ idProduct:CONFIG_USBD_PRODUCTID, -+ iManufacturer:CONFIG_USBD_MANUFACTURER, -+ iProduct:CONFIG_USBD_PRODUCT_NAME, -+ iSerialNumber:CONFIG_USBD_SERIAL_NUMBER_STR, -+}; -+ -+/************************************** -+** Other Variable -+**************************************/ -+static int storage_exit_flag = 0; -+static pid_t storage_pid = 0; -+static struct semaphore storage_sem; -+struct timer_list storage_usb_event_tim; -+ -+ -+/****************************************************************************** -+** Global Function -+******************************************************************************/ -+ -+void storage_urb_send(struct usb_device_instance* device, void* buffer, -+ int length) -+{ -+ int port = 0; -+ struct urb* urb; -+ -+ if(!(urb = usbd_alloc_urb(device, -+ device->function_instance_array + port, -+ CONFIG_USBD_STORAGE_IN_ENDPOINT, -+ length + 5 + in_pkt_sz))){ -+ printk(KERN_INFO "storage_fd: usbd_alloc_urb failed. length '%d'.\n", length); -+ return; -+ } -+ -+ if(buffer){ -+ memcpy(urb->buffer, buffer, length); -+ } -+ else{ -+ memset(urb->buffer, 0x00, length); -+ } -+ urb->actual_length = length; -+ -+ if(usbd_send_urb(urb)){ -+ printk(KERN_INFO "storage_fd: usbd_send_urb failed.\n"); -+ usbd_dealloc_urb(urb); -+ return; -+ } -+ -+ return; -+} -+ -+/****************************************************************************** -+** Local Function -+******************************************************************************/ -+ -+/************************************** -+** Called when a USB Device is created or destroyed -+**************************************/ -+ -+static int storage_thread(void *_c) -+{ -+ siginfo_t info; -+ unsigned long signr; -+ char buff[32]; -+ -+ /* current status set */ -+ daemonize(); -+ -+ /* PID set */ -+ storage_pid = current->pid; -+ -+ /* thread name set */ -+ sprintf(current->comm, STORAGE_THREAD_NAME); -+ (current)->nice = 10; -+ -+ /* signal register */ -+ spin_lock_irq(¤t->sigmask_lock); -+ siginitsetinv(¤t->blocked, -+ sigmask(SIGUSR1) | sigmask(SIGHUP) | sigmask(SIGKILL) | -+ sigmask(SIGSTOP) | sigmask(SIGCONT) | sigmask(SIGTERM) | -+ sigmask(SIGALRM)); -+ recalc_sigpending(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ /* media open */ -+ schedule_task_register( -+ (SCHEDULE_TASK_FUNC)storageproto_media_status_check, CONTEXT_STORAGE, -+ 0, 0, 0, 0); -+ -+ /* thread active indicate */ -+ sprintf(buff, "%d\n", storage_pid); -+ hotplug("usbdstorage", buff, "active"); -+ -+ for(;;){ -+ set_current_state(TASK_INTERRUPTIBLE); -+ -+ if (!signal_pending(current)) { -+ schedule(); -+ continue; -+ } -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ signr = dequeue_signal(¤t->blocked, &info); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ switch(signr) { -+ case SIGHUP: -+ /* media signal indicate */ -+ schedule_task_register( -+ (SCHEDULE_TASK_FUNC)storageproto_media_status_check, CONTEXT_STORAGE, -+ 0, 0, 0, 0); -+ -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: signal receive 'SIGHUP'.\n"); -+ break; -+ -+ default: -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: signal receive '%ld'\n", signr); -+ break; -+ } -+ -+ if(storage_exit_flag) break; -+ } -+ /* current status set */ -+ current->state = TASK_RUNNING; -+ -+ /* PID clear */ -+ storage_pid = 0; -+ -+ /* thread inactive indicate */ -+ hotplug("usbdstorage", buff, "inactive"); -+ -+ up(&storage_sem); -+ -+ return 0; -+} -+ -+static void storage_function_init(struct usb_bus_instance* bus, -+ struct usb_device_instance* device, -+ struct usb_function_driver* function_driver) -+{ -+ /* schedule task init */ -+ schedule_task_init(); -+ -+ /* storage protocol initialize */ -+ storageproto_init(); -+ -+ /* semaphore init */ -+ sema_init(&storage_sem, 0); -+ -+ /* timer initialize */ -+ init_timer(&storage_usb_event_tim); -+ -+ /* thread create */ -+ storage_pid = kernel_thread(storage_thread, NULL, 0); -+ -+ return; -+} -+ -+static void storage_function_exit(struct usb_device_instance* device) -+{ -+ /* thread kill */ -+ storage_exit_flag = 1; -+ kill_proc(storage_pid, SIGKILL, 1); -+ down(&storage_sem); -+ -+ /* delete timer */ -+ del_timer(&storage_usb_event_tim); -+ -+ /* storage protocol exit */ -+ storageproto_exit(); -+ -+ /* schedule task delete */ -+ schedule_task_all_unregister(); -+ -+ return; -+} -+ -+ -+/************************************** -+** Called to handle USB Events -+**************************************/ -+ -+static void storage_usb_event_delay_timeout(unsigned long param) -+{ -+ /* media signal indicate */ -+ schedule_task_register( -+ (SCHEDULE_TASK_FUNC)storageproto_usb_status_check, (int)param, -+ 0, 0, 0, 0); -+ -+ return; -+} -+ -+/* -+ * storage_event - process a device event -+ * @device: usb device -+ * @event: the event that happened -+ * -+ * Called by the usb device core layer to respond to various USB events. -+ * -+ * This routine IS called at interrupt time. Please use the usual precautions. -+ * -+ */ -+void storage_event(struct usb_device_instance* device, -+ usb_device_event_t event, int data) -+{ -+#if 0 -+ static struct { -+ usb_device_event_t event; -+ char* string; -+ } eventAnal[] = { -+ {DEVICE_UNKNOWN, "DEVICE_UNKNOWN"}, -+ {DEVICE_INIT, "DEVICE_INIT"}, -+ {DEVICE_CREATE, "DEVICE_CREATE"}, -+ {DEVICE_HUB_CONFIGURED, "DEVICE_HUB_CONFIGURED"}, -+ {DEVICE_RESET, "DEVICE_RESET"}, -+ {DEVICE_ADDRESS_ASSIGNED, "DEVICE_ADDRESS_ASSIGNED"}, -+ {DEVICE_CONFIGURED, "DEVICE_CONFIGURED"}, -+ {DEVICE_SET_INTERFACE, "DEVICE_SET_INTERFACE"}, -+ {DEVICE_SET_FEATURE, "DEVICE_SET_FEATURE"}, -+ {DEVICE_CLEAR_FEATURE, "DEVICE_CLEAR_FEATURE"}, -+ {DEVICE_DE_CONFIGURED, "DEVICE_DE_CONFIGURED"}, -+ {DEVICE_BUS_INACTIVE, "DEVICE_BUS_INACTIVE"}, -+ {DEVICE_BUS_ACTIVITY, "DEVICE_BUS_ACTIVITY"}, -+ {DEVICE_POWER_INTERRUPTION, "DEVICE_POWER_INTERRUPTION"}, -+ {DEVICE_HUB_RESET, "DEVICE_HUB_RESET"}, -+ {DEVICE_DESTROY, "DEVICE_DESTROY"}, -+ {DEVICE_FUNCTION_PRIVATE, "DEVICE_FUNCTION_PRIVATE"} -+ }; -+ int i; -+ -+ for(i=0; i<(sizeof(eventAnal)/sizeof(eventAnal[0])); i++){ -+ if(event == eventAnal[i].event){ -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: event receive '%s'.\n", -+ eventAnal[i].string); -+ break; -+ } -+ } -+ if(i == (sizeof(eventAnal)/sizeof(eventAnal[0]))){ -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: unknown event receive.\n"); -+ } -+#endif -+ -+ switch(event){ -+ case DEVICE_ADDRESS_ASSIGNED: -+ { -+ static int Is1stCheck = 1; -+ if(Is1stCheck){ -+ Is1stCheck = 0; -+ -+ /* delay timer set */ -+ del_timer(&storage_usb_event_tim); -+ storage_usb_event_tim.expires = jiffies + ((USB_EVENT_DELAY_TIM * HZ) / 1000); -+ storage_usb_event_tim.data = USB_DISCONNECT; -+ storage_usb_event_tim.function = storage_usb_event_delay_timeout; -+ add_timer(&storage_usb_event_tim); -+ break; -+ } -+ } -+ case DEVICE_BUS_ACTIVITY: -+ /* delay timer set */ -+ del_timer(&storage_usb_event_tim); -+ storage_usb_event_tim.expires = jiffies + ((USB_EVENT_DELAY_TIM * HZ) / 1000); -+ storage_usb_event_tim.data = USB_CONNECT; -+ storage_usb_event_tim.function = storage_usb_event_delay_timeout; -+ add_timer(&storage_usb_event_tim); -+ break; -+ -+ case DEVICE_BUS_INACTIVE: -+ /* delay timer set */ -+ del_timer(&storage_usb_event_tim); -+ storage_usb_event_tim.expires = jiffies + ((USB_EVENT_DELAY_TIM * HZ) / 1000); -+ storage_usb_event_tim.data = USB_DISCONNECT; -+ storage_usb_event_tim.function = storage_usb_event_delay_timeout; -+ add_timer(&storage_usb_event_tim); -+ break; -+ -+ case DEVICE_RESET: -+ schedule_task_register( -+ (SCHEDULE_TASK_FUNC)storageproto_usb_reset_ind, -+ 0, 0, 0, 0, 0); -+ break; -+ -+ default: -+ break; -+ } -+ -+ return; -+} -+ -+/* -+ * storage_recv_setup - called with a control URB -+ * @urb - pointer to struct urb -+ * -+ * Check if this is a setup packet, process the device request, put results -+ * back into the urb and return zero or non-zero to indicate success (DATA) -+ * or failure (STALL). -+ * -+ * This routine IS called at interrupt time. Please use the usual precautions. -+ * -+ */ -+int storage_recv_setup(struct urb* urb) -+{ -+ return 0; -+} -+ -+/* -+ * storage_recv_urb - called with a received URB -+ * @urb - pointer to struct urb -+ * -+ * Return non-zero if we failed and urb is still valid (not disposed) -+ * -+ * This routine IS called at interrupt time. Please use the usual precautions. -+ * -+ */ -+int storage_recv_urb(struct urb* urb) -+{ -+ int port = 0; // XXX compound device -+ struct usb_device_instance* device; -+ struct usb_function_instance* function; -+ -+ if(!urb || !(device = urb->device) || -+ !(function = device->function_instance_array + port)){ -+ return -EINVAL; -+ } -+ -+ if(urb->status != RECV_OK){ -+ return -EINVAL; -+ } -+ -+ /* URB urb_analysis */ -+ schedule_task_register( -+ (SCHEDULE_TASK_FUNC)storageproto_urb_analysis, (int)urb, -+ 0, 0, 0, 0); -+ -+ return 0; -+} -+ -+/* -+ * storage_urb_sent - called to indicate URB transmit finished -+ * @urb: pointer to struct urb -+ * @rc: result -+ * -+ * The usb device core layer will use this to let us know when an URB has -+ * been finished with. -+ * -+ * This routine IS called at interrupt time. Please use the usual precautions. -+ * -+ */ -+int storage_urb_sent(struct urb* urb, int rc) -+{ -+ int port = 0; // XXX compound device -+ struct usb_device_instance* device; -+ struct usb_function_instance* function; -+ -+ if(!urb || !(device = urb->device) || -+ !(function = device->function_instance_array + port)){ -+ return -EINVAL; -+ } -+ -+ usbd_dealloc_urb (urb); -+ -+ return 0; -+} -+ -+/************************************** -+** Proc file system -+**************************************/ -+ -+static ssize_t storage_proc_read(struct file* file, char* buf, size_t count, -+ loff_t* pos) -+{ -+ int len = 0, ret; -+ -+ if(*pos > 0) return 0; -+ -+ if((ret = storageproto_proc_read(file, buf + len, count - len, pos)) < 0){ -+ return ret; -+ } -+ len += ret; -+ -+ if((ret = schedule_task_proc_read(file, buf + len, count - len, pos)) < 0){ -+ return ret; -+ } -+ len += ret; -+ -+ return len; -+} -+ -+static struct file_operations StorageProcOps = { -+ read:storage_proc_read, -+}; -+ -+/************************************** -+** Module init and exit -+**************************************/ -+ -+struct usb_function_operations StorageFunctionOps = { -+ event:storage_event, -+ recv_urb:storage_recv_urb, -+ recv_setup:storage_recv_setup, -+ urb_sent:storage_urb_sent, -+ function_init:storage_function_init, -+ function_exit:storage_function_exit, -+}; -+ -+struct usb_function_driver StorageFunctionDriver = { -+ name:"Mass Storage", -+ ops:&StorageFunctionOps, -+ device_description:&StorageDeviceDescription, -+ configurations:sizeof (StorageDescription) / sizeof (struct usb_configuration_description), -+ configuration_description:StorageDescription, -+ this_module:THIS_MODULE, -+}; -+ -+/* -+ * net_modinit - module init -+ * -+ */ -+static int __init net_modinit(void) -+{ -+ struct proc_dir_entry* proc_entry; -+ -+ printk(KERN_INFO "storage_fd: %s (OUT=%d,IN=%d)\n", -+ __usbd_module_info, out_pkt_sz, in_pkt_sz); -+ -+ printk(KERN_INFO "storage_fd: vendorID: %x productID: %x\n", -+ CONFIG_USBD_VENDORID, CONFIG_USBD_PRODUCTID); -+ -+ // verify pkt sizes not too small -+ if (out_pkt_sz < 3 || in_pkt_sz < 3){ -+ printk(KERN_INFO "storage_fd: Rx pkt size %d or Tx pkt size %d too small\n", -+ out_pkt_sz, in_pkt_sz); -+ return (-EINVAL); -+ } -+ -+ if(vendor_id){ -+ StorageDeviceDescription.idVendor = vendor_id; -+ } -+ if(product_id){ -+ StorageDeviceDescription.idProduct = product_id; -+ } -+ -+ // register us with the usb device support layer -+ if(usbd_register_function(&StorageFunctionDriver)){ -+ printk(KERN_INFO "storage_fd: usbd_register_function failed.\n"); -+ return -EINVAL; -+ } -+ -+ // create proc entry -+ if ((proc_entry = create_proc_entry("usb-storage", 0, 0)) == NULL) { -+ usbd_deregister_function (&StorageFunctionDriver); -+ printk(KERN_INFO "storage_fd: create_proc_entry failed.\n"); -+ return -ENOMEM; -+ } -+ proc_entry->proc_fops = &StorageProcOps; -+ -+ return 0; -+} -+ -+/* -+ * function_exit - module cleanup -+ * -+ */ -+static void __exit net_modexit (void) -+{ -+ // de-register us with the usb device support layer -+ usbd_deregister_function (&StorageFunctionDriver); -+ -+ // remove proc entry -+ remove_proc_entry("usb-storage", NULL); -+ -+ return; -+} -+ -+module_init (net_modinit); -+module_exit (net_modexit); -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/storageproto.c linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.c ---- linux-2.4.18/drivers/usb/device/storage_fd/storageproto.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.c 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,1505 @@ -+/* -+ * linux/drivers/usb/device/storage_fd/storageproto.c - mass storage protocol library -+ * -+ * Copyright (c) 2003 Lineo Solutions, Inc. -+ * -+ * Written by Shunnosuke kabata -+ * -+ * 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 of the License, 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 File -+******************************************************************************/ -+#include <linux/config.h> -+#include <linux/module.h> -+ -+#include "../usbd-export.h" -+#include "../usbd-build.h" -+#include "../usbd-module.h" -+ -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/netdevice.h> -+#include <linux/skbuff.h> -+#include <linux/etherdevice.h> -+#include <linux/rtnetlink.h> -+#include <linux/smp_lock.h> -+#include <linux/ctype.h> -+#include <linux/timer.h> -+#include <linux/string.h> -+#include <linux/atmdev.h> -+#include <linux/pkt_sched.h> -+#include <linux/delay.h> -+#include <linux/blkdev.h> -+#include <linux/file.h> -+#include <asm/uaccess.h> -+#include <asm/system.h> -+#include <net/arp.h> -+ -+#include <linux/autoconf.h> -+ -+#include "../usbd.h" -+#include "../usbd-func.h" -+#include "../usbd-bus.h" -+#include "../usbd-inline.h" -+#include "../usbd-arch.h" -+#include "../hotplug.h" -+ -+#include "schedule_task.h" -+#include "storageproto.h" -+ -+/****************************************************************************** -+** macro define -+******************************************************************************/ -+ -+#define DEVICE_BLOCK_SIZE 512 -+ -+#define BLOCK_BUFFER_SIZE (1024 * 64) -+ -+#define DEF_NUMBER_OF_HEADS 0x10 -+#define DEF_SECTORS_PER_TRACK 0x20 -+ -+/****************************************************************************** -+** Structure Define -+******************************************************************************/ -+ -+typedef struct{ -+ unsigned char scsi_command; -+ unsigned char* command_name; -+ void (*scsi_func)(struct usb_device_instance*, -+ COMMAND_BLOCK_WRAPPER*); -+} SCSI_ANALYSIS_TBL; -+ -+typedef struct{ -+ unsigned char scsi_command; -+ unsigned char* command_name; -+ void (*bulkout_func)(struct usb_device_instance*, -+ void*, int); -+} SCSI_BULKOUT_ANALYSIS_TBL; -+ -+/****************************************************************************** -+** Variable Declaration -+******************************************************************************/ -+ -+/************************************** -+** Module Parameters -+**************************************/ -+ -+static char* storage_device = CONFIG_USBD_STORAGE_DEF_DEVICE_NAME; -+MODULE_PARM(storage_device, "s"); -+ -+/************************************** -+** Device Information -+**************************************/ -+ -+static struct file* DeviceFile = NULL; -+static int DeviceSize = 0; -+static int DeviceBlockSize = DEVICE_BLOCK_SIZE; -+static int DeviceWrProtect = WR_PROTECT_OFF; -+ -+/************************************** -+** Status -+**************************************/ -+ -+static int StorageStatus = STORAGE_IDLE; -+static int UsbStatus = USB_DISCONNECT; -+static int MediaStatus = MEDIA_EJECT; -+static int MediaChange = MEDIA_CHANGE_OFF; -+ -+/************************************** -+** Keep Information -+**************************************/ -+ -+static SCSI_REQUEST_SENSE_DATA RequestSenseData; -+static COMMAND_BLOCK_WRAPPER KeepCBW; -+static unsigned long BulkOutLength = 0; -+static unsigned char BlockBuffer[BLOCK_BUFFER_SIZE]; -+ -+/************************************** -+** Statistics -+**************************************/ -+static unsigned long StatMaxBulkInSize = 0; -+static unsigned long StatMaxBulkOutSize = 0; -+static unsigned long StatDevWriteError = 0; -+static unsigned long StatDevReadError = 0; -+static unsigned long StatDevFlushError = 0; -+static unsigned long StatWriteTimout = 0; -+static unsigned long StatMaxWriteTime = 0; -+ -+/************************************** -+** Timer -+**************************************/ -+static struct timer_list BulkOutTim; -+static struct timer_list MediaCheckTim; -+ -+/****************************************************************************** -+** Local Function -+******************************************************************************/ -+ -+static void storage_bulkout_timeout(unsigned long param) -+{ -+ /* statistics update */ -+ StatWriteTimout++; -+ printk(KERN_INFO "storage_fd: write bulk out timeout. length '%ld/%ld'.\n", -+ BulkOutLength, KeepCBW.dCBWDataTransferLength); -+ -+ return; -+} -+ -+static void media_check_timeout(unsigned long param) -+{ -+ /* media check */ -+ schedule_task_register( -+ (SCHEDULE_TASK_FUNC)storageproto_media_status_check, CONTEXT_TIMER, -+ 0, 0, 0, 0); -+ -+ return; -+} -+ -+static void request_sense_data_set(unsigned char sense_key, unsigned char asc, -+ unsigned char ascq, unsigned long info) -+{ -+ /* -+ * set REQUEST SENSE DATA -+ */ -+ -+ memset(&RequestSenseData, 0x00, sizeof(RequestSenseData)); -+ -+ RequestSenseData.ErrorCode = 0x70; -+ RequestSenseData.Valid = (info) ? 1 : 0; -+ RequestSenseData.SenseKey = sense_key; -+ memcpy(RequestSenseData.Information, &info, sizeof(info)); -+ RequestSenseData.AdditionalSenseLength = 0x0a; -+ RequestSenseData.AdditionalSenseCode = asc; -+ RequestSenseData.AdditionalSenseCodeQualifier = ascq; -+ -+ return; -+} -+ -+static void scsi_inquiry_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ SCSI_INQUIRY_DATA data; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned long data_len; -+ -+ /* -+ * data transport -+ */ -+ -+ memset(&data, 0x00, sizeof(data)); -+ -+ data.PeripheralDeviceType = 0x00; -+ data.RMB = 1; -+ data.ResponseDataFormat = 0x01; -+ data.AdditionalLength = 0x1f; -+ strncpy(data.VendorInformation, CONFIG_USBD_MANUFACTURER, -+ sizeof(data.VendorInformation)); -+ strncpy(data.ProductIdentification, CONFIG_USBD_PRODUCT_NAME, -+ sizeof(data.ProductIdentification)); -+ strncpy(data.ProductRevisionLevel, PRODUCT_REVISION_LEVEL, -+ sizeof(data.ProductRevisionLevel)); -+ -+ data_len = sizeof(data); -+ if(cbw->dCBWDataTransferLength < data_len){ -+ data_len = cbw->dCBWDataTransferLength; -+ } -+ -+ storage_urb_send(device, &data, data_len); -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len; -+ csw.bCSWStatus = 0; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_read_format_capacity_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ SCSI_READ_FORMAT_CAPACITY_DATA data; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned long block_num, data_len; -+ unsigned short block_len; -+ -+ /* -+ * data transport -+ */ -+ -+ block_num = 0xffffffff; -+ block_len = (unsigned short)DeviceBlockSize; -+ block_num = htonl(block_num); -+ block_len = htons(block_len); -+ -+ memset(&data, 0x00, sizeof(data)); -+ -+ data.CapacityListHeader.CapacityListLength = -+ sizeof(data.CurrentMaximumCapacityDescriptor); -+ memcpy(data.CurrentMaximumCapacityDescriptor.NumberofBlocks, &block_num, -+ sizeof(block_num)); -+ data.CurrentMaximumCapacityDescriptor.DescriptorCode = 0x03; -+ memcpy(data.CurrentMaximumCapacityDescriptor.BlockLength + 1, &block_len, -+ sizeof(block_len)); -+ -+ data_len = sizeof(data); -+ if(cbw->dCBWDataTransferLength < data_len){ -+ data_len = cbw->dCBWDataTransferLength; -+ } -+ -+ storage_urb_send(device, &data, data_len); -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len; -+ csw.bCSWStatus = 0; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_read_capacity_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ SCSI_READ_CAPACITY_DATA data; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char data_len, status = 0; -+ -+ if(DeviceFile == NULL){ -+ /* 0 clear */ -+ memset(&data, 0x00, sizeof(data)); -+ -+ /* data length set */ -+ data_len = cbw->dCBWDataTransferLength; -+ -+ /* status set */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ } -+ else -+ if(MediaChange == MEDIA_CHANGE_ON){ -+ /* 0 clear */ -+ memset(&data, 0x00, sizeof(data)); -+ -+ /* data length set */ -+ data_len = cbw->dCBWDataTransferLength; -+ -+ /* status set */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x06, 0x28, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ } -+ else{ -+ unsigned long last_lba, block_len; -+ -+ /* 0 clear */ -+ memset(&data, 0x00, sizeof(data)); -+ -+ /* data set */ -+ last_lba = (DeviceSize / DeviceBlockSize) - 1; -+ block_len = DeviceBlockSize; -+ last_lba = htonl(last_lba); -+ block_len = htonl(block_len); -+ -+ memcpy(data.LastLogicalBlockAddress, &last_lba, sizeof(last_lba)); -+ memcpy(data.BlockLengthInBytes, &block_len, sizeof(block_len)); -+ -+ /* data length set */ -+ data_len = sizeof(data); -+ -+ /* status set */ -+ status = 0; -+ } -+ -+ /* -+ * data transport -+ */ -+ -+ if(cbw->dCBWDataTransferLength < data_len){ -+ data_len = cbw->dCBWDataTransferLength; -+ } -+ -+ storage_urb_send(device, &data, data_len); -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_request_sense_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned long data_len; -+ -+ /* -+ * data transport -+ */ -+ -+ data_len = sizeof(RequestSenseData); -+ if(cbw->dCBWDataTransferLength < data_len){ -+ data_len = cbw->dCBWDataTransferLength; -+ } -+ -+ storage_urb_send(device, &RequestSenseData, data_len); -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len; -+ csw.bCSWStatus = 0; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_read_10_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ SCSI_READ_10_COMMAND* command = (SCSI_READ_10_COMMAND*)cbw->CBWCB; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char status = 0; -+ unsigned short len; -+ unsigned long lba, size, offset; -+ -+ memcpy(&lba, command->LogicalBlockAddress, sizeof(lba)); -+ memcpy(&len, command->TransferLength, sizeof(len)); -+ lba = ntohl(lba); -+ len = ntohs(len); -+ offset = lba * DeviceBlockSize; -+ size = cbw->dCBWDataTransferLength; -+ -+ if(DeviceFile == NULL){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ -+ /* -+ * data transport -+ */ -+ -+ storage_urb_send(device, NULL, size); -+ } -+ else -+ if(MediaChange == MEDIA_CHANGE_ON){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x06, 0x28, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ -+ /* -+ * data transport -+ */ -+ -+ storage_urb_send(device, NULL, size); -+ } -+ else{ -+ unsigned long count, read_size; -+ -+ /* -+ * data transport -+ */ -+ -+ /* device seek */ -+ DeviceFile->f_op->llseek(DeviceFile, offset, 0); -+ -+ /* device read */ -+ for(count = size; count; count -= read_size){ -+ read_size = (count > sizeof(BlockBuffer)) ? -+ sizeof(BlockBuffer) : count; -+ if(DeviceFile && -+ DeviceFile->f_op->read(DeviceFile, BlockBuffer, read_size, -+ &DeviceFile->f_pos) != read_size){ -+ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ -+ /* statistics update */ -+ StatDevReadError++; -+ printk(KERN_INFO "storage_fd: device read error. length '%ld'.\n", read_size); -+ } -+ -+ storage_urb_send(device, BlockBuffer, read_size); -+ } -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - size; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_mode_sense_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ static READ_WRITE_ERROR_RECOVERY_PAGE page_01 = { -+ PageCode:0x01, -+ PageLength:0x0A, -+ ReadRetryCount:0x03, -+ WriteRetryCount:0x80, -+ }; -+ static FLEXIBLE_DISK_PAGE page_05 = { -+ PageCode:0x05, -+ PageLength:0x1E, -+ TransferRate:{0x00, 0xFA}, -+ NumberofHeads:0xA0, -+ SectorsperTrack:0x00, -+ DataBytesperSector:{0x02, 0x00}, -+ NumberofCylinders:{0x00, 0x00}, -+ MotorOnDelay:0x05, -+ MotorOffDelay:0x1E, -+ MediumRotationRate:{0x01, 0x68}, -+ }; -+ static REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE page_1b = { -+ PageCode:0x1B, -+ PageLength:0x0A, -+ TLUN:0x01, -+ }; -+ static TIMER_AND_PROTECT_PAGE page_1c = { -+ PageCode:0x1c, -+ PageLength:0x06, -+ InactivityTimeMultiplier:0x0A, -+ }; -+ -+ -+ SCSI_MODE_SENSE_COMMAND* command = (SCSI_MODE_SENSE_COMMAND*)cbw->CBWCB; -+ SCSI_MODE_SENSE_DATA data; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char data_len, status = 0; -+ unsigned short cylinder, sector; -+ unsigned long size; -+ -+ /* -+ * data transport -+ */ -+ -+ memset(&data, 0x00, sizeof(data)); -+ -+ /* set write protect */ -+ data.ModeParameterHeader.WP = DeviceWrProtect; -+ -+ /* set Flexible Disk Page */ -+ if(DeviceFile == NULL){ -+ sector = (unsigned short)DeviceBlockSize; -+ cylinder = 0; -+ sector = htons(sector); -+ cylinder = htons(cylinder); -+ -+ page_05.NumberofHeads = 0; -+ page_05.SectorsperTrack = 0; -+ memcpy(page_05.DataBytesperSector, §or, sizeof(sector)); -+ memcpy(page_05.NumberofCylinders, &cylinder, sizeof(cylinder)); -+ } -+ else{ -+ sector = (unsigned short)DeviceBlockSize; -+ size = DEF_NUMBER_OF_HEADS * DEF_SECTORS_PER_TRACK * sector; -+ cylinder = DeviceSize / size; -+ sector = htons(sector); -+ cylinder = htons(cylinder); -+ -+ page_05.NumberofHeads = DEF_NUMBER_OF_HEADS; -+ page_05.SectorsperTrack = DEF_SECTORS_PER_TRACK; -+ memcpy(page_05.DataBytesperSector, §or, sizeof(sector)); -+ memcpy(page_05.NumberofCylinders, &cylinder, sizeof(cylinder)); -+ } -+ -+ if(command->PC == 0 && command->PageCode == 0x01){ -+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_01); -+ data.ModeParameterHeader.ModeDataLength = data_len - 1; -+ memcpy(&data.ModePages, &page_01, sizeof(page_01)); -+ } -+ else -+ if(command->PC == 0 && command->PageCode == 0x05){ -+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_05); -+ data.ModeParameterHeader.ModeDataLength = data_len - 1; -+ memcpy(&data.ModePages, &page_05, sizeof(page_05)); -+ } -+ else -+ if(command->PC == 0 && command->PageCode == 0x1b){ -+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_1b); -+ data.ModeParameterHeader.ModeDataLength = data_len - 1; -+ memcpy(&data.ModePages, &page_1b, sizeof(page_1b)); -+ } -+ else -+ if(command->PC == 0 && command->PageCode == 0x1c){ -+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_1c); -+ data.ModeParameterHeader.ModeDataLength = data_len - 1; -+ memcpy(&data.ModePages, &page_1c, sizeof(page_1c)); -+ } -+ else -+ if(command->PC == 0 && command->PageCode == 0x3f){ -+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_ALL_PAGES); -+ data.ModeParameterHeader.ModeDataLength = data_len - 1; -+ memcpy(&data.ModePages.ModeAllPages.ReadWriteErrorRecoveryPage, -+ &page_01, sizeof(page_01)); -+ memcpy(&data.ModePages.ModeAllPages.FlexibleDiskPage, -+ &page_05, sizeof(page_05)); -+ memcpy(&data.ModePages.ModeAllPages.RemovableBlockAccessCapabilitiesPage, -+ &page_1b, sizeof(page_1b)); -+ memcpy(&data.ModePages.ModeAllPages.TimerAndProtectPage, -+ &page_1c, sizeof(page_1c)); -+ } -+ else{ -+ /* command fail */ -+ status = 1; -+ data_len = cbw->dCBWDataTransferLength; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x05, 0x24, 0x00, 0x00); -+ } -+ -+ if(cbw->dCBWDataTransferLength < data_len){ -+ data_len = cbw->dCBWDataTransferLength; -+ } -+ -+ storage_urb_send(device, &data, data_len); -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_test_unit_ready_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char status = 0; -+ -+ if(DeviceFile == NULL){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ } -+ else -+ if(MediaChange == MEDIA_CHANGE_ON){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x06, 0x28, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_prevent_allow_medium_removal_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL_COMMAND* command = (SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL_COMMAND*)cbw->CBWCB; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char status = 0; -+ -+ if(command->Prevent){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x05, 0x24, 0x00, 0x00); -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_start_stop_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ SCSI_START_STOP_COMMAND* command = (SCSI_START_STOP_COMMAND*)cbw->CBWCB; -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char status = 0; -+ -+ if(DeviceFile == NULL){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ } -+ else -+ if(MediaChange == MEDIA_CHANGE_ON){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x06, 0x28, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ } -+ else -+ if(command->Start && command->LoEj){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x05, 0x24, 0x00, 0x00); -+ } -+ -+ /* device buffer flush */ -+ if(DeviceFile && DeviceFile->f_op->ioctl(DeviceFile->f_dentry->d_inode, -+ DeviceFile, BLKFLSBUF, 0) != 0){ -+ /* statistics update */ -+ StatDevFlushError++; -+ printk(KERN_INFO "storage_fd: device flush error.\n"); -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_write_10_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ /* status set */ -+ BulkOutLength = 0; -+ StorageStatus = STORAGE_BULKOUT; -+ -+ /* timer set */ -+ del_timer(&BulkOutTim); -+ BulkOutTim.expires = jiffies + ((WR_BULKOUT_CHK_TIM * HZ) / 1000); -+ BulkOutTim.data = 0; -+ BulkOutTim.function = storage_bulkout_timeout; -+ add_timer(&BulkOutTim); -+ -+ return; -+} -+ -+static void scsi_verify_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char status = 0; -+ -+ if(DeviceFile == NULL){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ } -+ else -+ if(MediaChange == MEDIA_CHANGE_ON){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x06, 0x28, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ return; -+} -+ -+static void scsi_unsupport_analysis(struct usb_device_instance* device, -+ COMMAND_BLOCK_WRAPPER* cbw) -+{ -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char data_len = 0; -+ -+ if(((cbw->bmCBWFlags & 0x80) == 0x00) && (cbw->dCBWDataTransferLength)){ -+ /* BLKOUT */ -+ -+ /* status set */ -+ BulkOutLength = 0; -+ StorageStatus = STORAGE_BULKOUT; -+ } -+ else{ -+ /* BLKIN */ -+ -+ if(cbw->dCBWDataTransferLength){ -+ data_len = cbw->dCBWDataTransferLength; -+ storage_urb_send(device, NULL, data_len); -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = cbw->dCBWTag; -+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len; -+ csw.bCSWStatus = 0x01; -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ } -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x05, 0x20, 0x00, 0x00); -+ -+ return; -+} -+ -+static void scsi_bulkout_write_10_analysis(struct usb_device_instance* device, -+ void* buffer, int length) -+{ -+ COMMAND_STATUS_WRAPPER csw; -+ unsigned char status = 0; -+ unsigned long buff_used_len, buff_offset; -+ unsigned long s_tick, e_tick, wr_tick; -+ -+ buff_offset = BulkOutLength % sizeof(BlockBuffer); -+ -+ memcpy(BlockBuffer + buff_offset, buffer, length); -+ BulkOutLength += length; -+ -+ buff_used_len = BulkOutLength % sizeof(BlockBuffer); -+ if(buff_used_len == 0) buff_used_len = sizeof(BlockBuffer); -+ -+ /* delete timer */ -+ if(BulkOutLength >= KeepCBW.dCBWDataTransferLength){ -+ del_timer(&BulkOutTim); -+ } -+ -+ if(buff_used_len >= sizeof(BlockBuffer) || -+ BulkOutLength >= KeepCBW.dCBWDataTransferLength){ -+ -+ /* buffer full */ -+ SCSI_WRITE_10_COMMAND* command = (SCSI_WRITE_10_COMMAND*)&KeepCBW.CBWCB; -+ unsigned short len; -+ unsigned long lba, offset; -+ -+ memcpy(&lba, command->LogicalBlockAddress, sizeof(lba)); -+ memcpy(&len, command->TransferLength, sizeof(len)); -+ lba = ntohl(lba); -+ len = ntohs(len); -+ -+ offset = (lba * DeviceBlockSize) + -+ (sizeof(BlockBuffer) * ((BulkOutLength - 1) / sizeof(BlockBuffer))); -+ -+ /* device check */ -+ if(DeviceFile && -+ MediaChange != MEDIA_CHANGE_ON && -+ DeviceWrProtect != WR_PROTECT_ON){ -+ -+ /* write before jiffies get */ -+ s_tick = jiffies; -+ -+ /* device seek */ -+ DeviceFile->f_op->llseek(DeviceFile, offset, 0); -+ -+ /* device write */ -+ if(DeviceFile->f_op->write(DeviceFile, BlockBuffer, buff_used_len, -+ &DeviceFile->f_pos) != buff_used_len){ -+ /* statistics update */ -+ StatDevWriteError++; -+ printk(KERN_INFO "storage_fd: device write error. length '%ld'.\n", buff_used_len); -+ } -+ -+ /* write after jiffies get */ -+ e_tick = jiffies; -+ -+ /* statistics update */ -+ wr_tick = e_tick - s_tick; -+ if(wr_tick > StatMaxWriteTime){ -+ StatMaxWriteTime = wr_tick; -+ } -+ } -+ } -+ -+ if(BulkOutLength >= KeepCBW.dCBWDataTransferLength){ -+ if(DeviceFile == NULL){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00); -+ } -+ else -+ if(MediaChange == MEDIA_CHANGE_ON){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x06, 0x28, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ } -+ else -+ if(DeviceWrProtect == WR_PROTECT_ON){ -+ /* command fail */ -+ status = 1; -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x07, 0x27, 0x00, 0x00); -+ -+ /* media change flag off */ -+ MediaChange = MEDIA_CHANGE_OFF; -+ } -+ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = KeepCBW.dCBWTag; -+ csw.dCSWDataResidue = KeepCBW.dCBWDataTransferLength - BulkOutLength; -+ csw.bCSWStatus = status; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ /* status reset */ -+ BulkOutLength = 0; -+ StorageStatus = STORAGE_IDLE; -+ -+ /* flush before jiffies get */ -+ s_tick = jiffies; -+ -+ /* device buffer flush */ -+ if(DeviceFile && DeviceFile->f_op->ioctl(DeviceFile->f_dentry->d_inode, -+ DeviceFile, BLKFLSBUF, 0) != 0){ -+ /* statistics update */ -+ StatDevFlushError++; -+ printk(KERN_INFO "storage_fd: device flush error.\n"); -+ } -+ -+ /* flush after jiffies get */ -+ e_tick = jiffies; -+ -+ /* statistics update */ -+ wr_tick = e_tick - s_tick; -+ if(wr_tick > StatMaxWriteTime){ -+ StatMaxWriteTime = wr_tick; -+ } -+ -+ } -+ -+ return; -+} -+ -+static void scsi_bulkout_unsupport_analysis(struct usb_device_instance* device, -+ void* buffer, int length) -+{ -+ COMMAND_STATUS_WRAPPER csw; -+ -+ BulkOutLength += length; -+ -+ if(BulkOutLength >= KeepCBW.dCBWDataTransferLength){ -+ /* -+ * status transport -+ */ -+ -+ memset(&csw, 0x00, sizeof(csw)); -+ -+ csw.dCSWSignature = CSW_SIGNATURE; -+ csw.dCSWTag = KeepCBW.dCBWTag; -+ csw.dCSWDataResidue = KeepCBW.dCBWDataTransferLength - BulkOutLength; -+ csw.bCSWStatus = 1; -+ -+ storage_urb_send(device, &csw, sizeof(csw)); -+ -+ /* error code save REQUEST SENSE */ -+ request_sense_data_set(0x05, 0x20, 0x00, 0x00); -+ -+ /* status reset */ -+ BulkOutLength = 0; -+ StorageStatus = STORAGE_IDLE; -+ } -+ -+ return; -+} -+ -+/****************************************************************************** -+** Global Function -+******************************************************************************/ -+ -+static SCSI_ANALYSIS_TBL ScsiAnalysisTbl[] = { -+ {SCSI_FORMAT_UNT, "SCSI_FORMAT_UNT", NULL}, -+ {SCSI_INQUIRY, "SCSI_INQUIRY", scsi_inquiry_analysis}, -+ {SCSI_START_STOP, "SCSI_START_STOP", scsi_start_stop_analysis}, -+ {SCSI_MODE_SELECT, "SCSI_MODE_SELECT", NULL}, -+ {SCSI_MODE_SENSE, "SCSI_MODE_SENSE", scsi_mode_sense_analysis}, -+ {SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL, "SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL", scsi_prevent_allow_medium_removal_analysis}, -+ {SCSI_READ_10, "SCSI_READ_10", scsi_read_10_analysis}, -+ {SCSI_READ_12, "SCSI_READ_12", NULL}, -+ {SCSI_READ_CAPACITY, "SCSI_READ_CAPACITY", scsi_read_capacity_analysis}, -+ {SCSI_READ_FORMAT_CAPACITY, "SCSI_READ_FORMAT_CAPACITY", scsi_read_format_capacity_analysis}, -+ {SCSI_REQUEST_SENSE, "SCSI_REQUEST_SENSE", scsi_request_sense_analysis}, -+ {SCSI_REZERO_UNIT, "SCSI_REZERO_UNIT", NULL}, -+ {SCSI_SEEK_10, "SCSI_SEEK_10", NULL}, -+ {SCSI_SEND_DIAGNOSTIC, "SCSI_SEND_DIAGNOSTIC", NULL}, -+ {SCSI_TEST_UNIT_READY, "SCSI_TEST_UNIT_READY", scsi_test_unit_ready_analysis}, -+ {SCSI_VERIFY, "SCSI_VERIFY", scsi_verify_analysis}, -+ {SCSI_WRITE_10, "SCSI_WRITE_10", scsi_write_10_analysis}, -+ {SCSI_WRITE_12, "SCSI_WRITE_12", NULL}, -+ {SCSI_WRITE_AND_VERIFY, "SCSI_WRITE_AND_VERIFY", NULL} -+}; -+ -+static SCSI_BULKOUT_ANALYSIS_TBL ScsiBlkOutAnalysisTbl[] = { -+ {SCSI_WRITE_10, "SCSI_WRITE_10", scsi_bulkout_write_10_analysis}, -+}; -+ -+void storageproto_urb_analysis(struct urb* urb) -+{ -+ COMMAND_BLOCK_WRAPPER* cbw = (COMMAND_BLOCK_WRAPPER*)urb->buffer; -+ int i; -+ -+ /* status BLKOUT check */ -+ if(StorageStatus == STORAGE_BULKOUT){ -+ for(i = 0; -+ i < sizeof(ScsiBlkOutAnalysisTbl) / sizeof(SCSI_ANALYSIS_TBL); -+ i++){ -+ if(ScsiBlkOutAnalysisTbl[i].scsi_command == KeepCBW.CBWCB[0]){ -+ if(ScsiBlkOutAnalysisTbl[i].bulkout_func){ -+ ScsiBlkOutAnalysisTbl[i].bulkout_func(urb->device, -+ urb->buffer, -+ urb->actual_length); -+ goto RETURN_LABEL; -+ } -+ break; -+ } -+ } -+ scsi_bulkout_unsupport_analysis(urb->device, urb->buffer, urb->actual_length); -+ goto RETURN_LABEL; -+ } -+ -+ /* signature check */ -+ if(cbw->dCBWSignature != CBW_SIGNATURE){ -+ printk(KERN_INFO "storage_fd: signature error. '0x%08lx'.\n", -+ cbw->dCBWSignature); -+ goto RETURN_LABEL; -+ } -+ -+ /* statistics set */ -+ if(cbw->dCBWDataTransferLength){ -+ if(((cbw->bmCBWFlags & 0x80) == 0x00) && (cbw->dCBWDataTransferLength)){ -+ /* BULK OUT */ -+ if(StatMaxBulkOutSize < cbw->dCBWDataTransferLength){ -+ StatMaxBulkOutSize = cbw->dCBWDataTransferLength; -+ } -+ } -+ else{ -+ /* BULK IN */ -+ if(StatMaxBulkInSize < cbw->dCBWDataTransferLength){ -+ StatMaxBulkInSize = cbw->dCBWDataTransferLength; -+ } -+ } -+ } -+ -+ /* save CBW and set storage status */ -+ memcpy(&KeepCBW, cbw, sizeof(KeepCBW)); -+ -+ /* UFI command analysis */ -+ for(i = 0; i < sizeof(ScsiAnalysisTbl) / sizeof(SCSI_ANALYSIS_TBL); i++){ -+ if(ScsiAnalysisTbl[i].scsi_command == cbw->CBWCB[0]){ -+ if(ScsiAnalysisTbl[i].scsi_func){ -+ ScsiAnalysisTbl[i].scsi_func(urb->device, cbw); -+ goto RETURN_LABEL; -+ } -+ break; -+ } -+ } -+ -+ scsi_unsupport_analysis(urb->device, cbw); -+ printk(KERN_INFO "storage_fd: SCSI command error. '0x%02x'.\n", -+ cbw->CBWCB[0]); -+ goto RETURN_LABEL; -+ -+RETURN_LABEL: -+ -+ /* URB free */ -+ usbd_recycle_urb(urb); -+ -+ return; -+} -+ -+int storageproto_device_open_check(void) -+{ -+ struct file* file; -+ struct inode* inode; -+ kdev_t dev; -+ int read_org; -+ -+ /* device already open check */ -+ if(DeviceFile){ -+ storageproto_device_close(); -+ } -+ -+ /* device open */ -+ file = filp_open(storage_device, O_RDWR, 0000); -+ if(IS_ERR(file)){ -+ file = filp_open(storage_device, O_RDONLY, 0000); -+ if(IS_ERR(file)){ -+ storageproto_device_close(); -+ return MEDIA_EJECT; -+ } -+ DeviceWrProtect = WR_PROTECT_ON; -+ } -+ -+ file->f_op->llseek(file, 0, 0); -+ if(file->f_op->read(file, (void*)&read_org, sizeof(read_org), &file->f_pos) -+ != sizeof(read_org)){ -+ filp_close(file, NULL); -+ storageproto_device_close(); -+ return MEDIA_EJECT; -+ } -+ -+ /* struct file pointer save */ -+ DeviceFile = file; -+ -+ /* device information */ -+ inode = file->f_dentry->d_inode; -+ dev = inode->i_rdev; -+ -+ if (blk_size[MAJOR(dev)]){ -+ DeviceSize = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS; -+ } -+ else{ -+ DeviceSize = INT_MAX << BLOCK_SIZE_BITS; -+ } -+ -+ if(blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)]){ -+ DeviceBlockSize = DEVICE_BLOCK_SIZE; -+ } -+ else{ -+ DeviceBlockSize = DEVICE_BLOCK_SIZE; -+ } -+ -+ return MEDIA_INSERT; -+} -+ -+void storageproto_device_close(void) -+{ -+ if(DeviceFile){ -+ filp_close(DeviceFile, NULL); -+ DeviceFile = NULL; -+ DeviceSize = 0; -+ DeviceBlockSize = DEVICE_BLOCK_SIZE; -+ DeviceWrProtect = WR_PROTECT_OFF; -+ } -+ -+ return; -+} -+ -+void storageproto_usb_status_check(int status) -+{ -+ static int Is1stCheck = 1; -+ -+ /* USB status check */ -+ if(Is1stCheck){ -+ Is1stCheck = 0; -+ } -+ else{ -+ if(UsbStatus == status) goto RETURN_LABEL; -+ } -+ -+ /* set status */ -+ UsbStatus = status; -+ -+ switch(UsbStatus){ -+ case USB_CONNECT: -+ /* media status check */ -+ storageproto_media_status_check(CONTEXT_SCHEDULE); -+ -+ switch(MediaStatus){ -+ case MEDIA_EJECT: -+ break; -+ -+ case MEDIA_INSERT: -+ hotplug("usbdstorage", storage_device, "umount"); -+ break; -+ -+ default: -+ break; -+ } -+ hotplug("usbdstorage", storage_device, "connect"); -+ break; -+ -+ case USB_DISCONNECT: -+ /* device close */ -+ storageproto_device_close(); -+ -+ switch(MediaStatus){ -+ case MEDIA_EJECT: -+ break; -+ -+ case MEDIA_INSERT: -+ hotplug("usbdstorage", storage_device, "mount"); -+ break; -+ -+ default: -+ break; -+ } -+ hotplug("usbdstorage", storage_device, "disconnect"); -+ break; -+ -+ default: -+ break; -+ } -+ -+RETURN_LABEL: -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: USB check '%s' '%s' 'file:%p'.\n", -+ (UsbStatus) ? "USB_CONNECT" : "USB_DISCONNECT", -+ (MediaStatus) ? "MEDIA_INSERT" : "MEDIA_EJECT", DeviceFile); -+ -+ return; -+} -+ -+void storageproto_media_status_check(int call_context) -+{ -+ static unsigned long RetryCount = 0; -+ int status; -+ -+ /* media open check */ -+ status = storageproto_device_open_check(); -+ -+ /* media status check retry */ -+ if(status == MEDIA_EJECT){ -+ switch(call_context){ -+ case CONTEXT_STORAGE: -+ -+ /* retry counter init */ -+ RetryCount = 0; -+ -+ /* timer set */ -+ del_timer(&MediaCheckTim); -+ MediaCheckTim.expires = jiffies + ((MEDIA_CHECK_TIM * HZ) / 1000); -+ MediaCheckTim.data = 0; -+ MediaCheckTim.function = media_check_timeout; -+ add_timer(&MediaCheckTim); -+ -+ break; -+ -+ case CONTEXT_TIMER: -+ -+ /* retry counter update */ -+ RetryCount++; -+ -+ /* retry counter check */ -+ if(RetryCount >= MEDIA_CHECK_RETRY) break; -+ -+ /* timer set */ -+ del_timer(&MediaCheckTim); -+ MediaCheckTim.expires = jiffies + ((MEDIA_CHECK_TIM * HZ) / 1000); -+ MediaCheckTim.data = 0; -+ MediaCheckTim.function = media_check_timeout; -+ add_timer(&MediaCheckTim); -+ -+ break; -+ -+ default: -+ break; -+ } -+ } -+ else -+ if(status == MEDIA_INSERT){ -+ /* delete timer */ -+ del_timer(&MediaCheckTim); -+ } -+ -+ /* media status check */ -+ if(status == MediaStatus){ -+ if(UsbStatus == USB_DISCONNECT){ -+ storageproto_device_close(); -+ } -+ if(MediaStatus == MEDIA_INSERT){ -+ if(call_context == CONTEXT_STORAGE || call_context == CONTEXT_TIMER){ -+ MediaChange = MEDIA_CHANGE_ON; -+ } -+ } -+ goto RETURN_LABEL; -+ } -+ -+ /* set status */ -+ MediaStatus = status; -+ -+ switch(MediaStatus){ -+ case MEDIA_INSERT: -+ /* set status */ -+ MediaChange = MEDIA_CHANGE_ON; -+ -+ switch(UsbStatus){ -+ case USB_DISCONNECT: -+ storageproto_device_close(); -+ break; -+ -+ case USB_CONNECT: -+ break; -+ -+ default: -+ break; -+ } -+ hotplug("usbdstorage", storage_device, "insert"); -+ break; -+ -+ case MEDIA_EJECT: -+ switch(UsbStatus){ -+ case USB_DISCONNECT: -+ storageproto_device_close(); -+ break; -+ -+ case USB_CONNECT: -+ break; -+ -+ default: -+ break; -+ } -+ hotplug("usbdstorage", storage_device, "eject"); -+ break; -+ -+ default: -+ break; -+ } -+ -+RETURN_LABEL: -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: media check. '%s' '%s' 'file:%p' '%s'.\n", -+ (UsbStatus) ? "USB_CONNECT" : "USB_DISCONNECT", -+ (MediaStatus) ? "MEDIA_INSERT" : "MEDIA_EJECT", DeviceFile, -+ (call_context == CONTEXT_SCHEDULE) ? "CONTEXT_SCHEDULE" : -+ (call_context == CONTEXT_STORAGE) ? "CONTEXT_STORAGE" : "CONTEXT_TIMER"); -+ -+ return; -+} -+ -+void storageproto_usb_reset_ind(void) -+{ -+ /* status reset */ -+ BulkOutLength = 0; -+ StorageStatus = STORAGE_IDLE; -+ -+ DBG_STORAGE_FD(KERN_INFO "storage_fd: storage protocol reset.\n"); -+ -+ return; -+} -+ -+void storageproto_init(void) -+{ -+ /* timer init */ -+ init_timer(&BulkOutTim); -+ -+ /* timer init */ -+ init_timer(&MediaCheckTim); -+ -+ return; -+} -+ -+void storageproto_exit(void) -+{ -+ /* device close */ -+ storageproto_device_close(); -+ -+ /* delete timer */ -+ del_timer(&BulkOutTim); -+ -+ /* delete timer */ -+ del_timer(&MediaCheckTim); -+ -+ return; -+} -+ -+ssize_t storageproto_proc_read(struct file* file, char* buf, size_t count, -+ loff_t* pos) -+{ -+ char string[1024]; -+ int len = 0; -+ -+ len += sprintf(string + len, "Protocol status:%s\n", -+ (StorageStatus == STORAGE_IDLE) ? "STORAGE_IDLE" : -+ (StorageStatus == STORAGE_BULKIN) ? "STORAGE_BULKIN" : -+ "STORAGE_BULKOUT"); -+ -+ len += sprintf(string + len, "USB status:%s\n", -+ (UsbStatus == USB_DISCONNECT) ? "USB_DISCONNECT" : -+ "USB_CONNECT"); -+ -+ len += sprintf(string + len, "Media status:%s\n", -+ (MediaStatus == MEDIA_EJECT) ? "MEDIA_EJECT" : -+ "MEDIA_INSERT"); -+ -+ len += sprintf(string + len, "Media chage:%s\n", -+ (MediaChange == MEDIA_CHANGE_OFF) ? "MEDIA_CHANGE_OFF" : -+ "MEDIA_CHANGE_ON"); -+ -+ len += sprintf(string + len, "Device name:%s\n", -+ storage_device); -+ -+ len += sprintf(string + len, "Device file descriptor:0x%p\n", -+ DeviceFile); -+ -+ len += sprintf(string + len, "Device size:0x%d\n", -+ DeviceSize); -+ -+ len += sprintf(string + len, "Device block size:0x%d\n", -+ DeviceBlockSize); -+ -+ len += sprintf(string + len, "Device write protect:%s\n", -+ (DeviceWrProtect == WR_PROTECT_OFF) ? "WR_PROTECT_OFF": -+ "WR_PROTECT_ON"); -+ -+ len += sprintf(string + len, "Bulk in max size:%ld\n", -+ StatMaxBulkInSize); -+ -+ len += sprintf(string + len, "Bulk out max size:%ld\n", -+ StatMaxBulkOutSize); -+ -+ len += sprintf(string + len, "device write error:%ld\n", -+ StatDevWriteError); -+ -+ len += sprintf(string + len, "device read error:%ld\n", -+ StatDevReadError); -+ -+ len += sprintf(string + len, "device flush error:%ld\n", -+ StatDevFlushError); -+ -+ len += sprintf(string + len, "write data bulk out timout:%ld\n", -+ StatWriteTimout); -+ -+ len += sprintf(string + len, "device write max time:%ld msec\n", -+ (StatMaxWriteTime * 1000) / HZ); -+ -+ *pos += len; -+ if(len > count){ -+ len = -EINVAL; -+ } -+ else -+ if(len > 0 && copy_to_user(buf, string, len)) { -+ len = -EFAULT; -+ } -+ -+ return len; -+} -+ -diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/storageproto.h linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.h ---- linux-2.4.18/drivers/usb/device/storage_fd/storageproto.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.h 2003-11-07 05:34:43.000000000 +0300 -@@ -0,0 +1,585 @@ -+/* -+ * linux/drivers/usb/device/storage_fd/storageproto.h - mass storage protocol library header -+ * -+ * Copyright (c) 2003 Lineo Solutions, Inc. -+ * -+ * Written by Shunnosuke kabata -+ * -+ * 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 of the License, 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 _STORAGEPROTO_H_ -+#define _STORAGEPROTO_H_ -+ -+/****************************************************************************** -+** Macro Define -+******************************************************************************/ -+ -+/************************************** -+** Class Code -+**************************************/ -+ -+/* -+ * Class -+ */ -+ -+#define MASS_STORAGE_CLASS 0x08 -+ -+/* -+ * SubClass -+ */ -+ -+#define MASS_STORAGE_SUBCLASS_RBC 0x01 -+#define MASS_STORAGE_SUBCLASS_SFF8020I 0x02 -+#define MASS_STORAGE_SUBCLASS_QIC157 0x03 -+#define MASS_STORAGE_SUBCLASS_UFI 0x04 -+#define MASS_STORAGE_SUBCLASS_SFF8070I 0x05 -+#define MASS_STORAGE_SUBCLASS_SCSI 0x06 -+ -+/* -+ * Protocol -+ */ -+ -+#define MASS_STORAGE_PROTO_CBI_WITH_COMP 0x00 -+#define MASS_STORAGE_PROTO_CBI_NO_COMP 0x01 -+#define MASS_STORAGE_PROTO_BULK_ONLY 0x50 -+ -+/************************************** -+** SCSI Command -+**************************************/ -+ -+#define SCSI_FORMAT_UNT 0x04 -+#define SCSI_INQUIRY 0x12 -+#define SCSI_START_STOP 0x1b -+#define SCSI_MODE_SELECT 0x55 -+#define SCSI_MODE_SENSE 0x1a -+#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e -+#define SCSI_READ_10 0x28 -+#define SCSI_READ_12 0xa8 -+#define SCSI_READ_CAPACITY 0x25 -+#define SCSI_READ_FORMAT_CAPACITY 0x23 -+#define SCSI_REQUEST_SENSE 0x03 -+#define SCSI_REZERO_UNIT 0x01 -+#define SCSI_SEEK_10 0x2b -+#define SCSI_SEND_DIAGNOSTIC 0x1d -+#define SCSI_TEST_UNIT_READY 0x00 -+#define SCSI_VERIFY 0x2f -+#define SCSI_WRITE_10 0x2a -+#define SCSI_WRITE_12 0xaa -+#define SCSI_WRITE_AND_VERIFY 0x2e -+ -+/************************************** -+** SCSI Command Parameter -+**************************************/ -+ -+#define CBW_SIGNATURE 0x43425355 /* USBC */ -+#define CSW_SIGNATURE 0x53425355 /* USBS */ -+ -+#define PRODUCT_REVISION_LEVEL "1.00" -+ -+/************************************** -+** Status -+**************************************/ -+ -+#define WR_PROTECT_OFF 0 -+#define WR_PROTECT_ON 1 -+ -+#define STORAGE_IDLE 0 -+#define STORAGE_BULKIN 1 -+#define STORAGE_BULKOUT 2 -+ -+#define USB_DISCONNECT 0 -+#define USB_CONNECT 1 -+ -+#define MEDIA_EJECT 0 -+#define MEDIA_INSERT 1 -+ -+#define MEDIA_CHANGE_OFF 0 -+#define MEDIA_CHANGE_ON 1 -+ -+/************************************** -+** Mass Storage Thread Name -+**************************************/ -+ -+#define STORAGE_THREAD_NAME "usbdstorage" -+ -+/************************************** -+** Media Signal Delay Time(ms) -+**************************************/ -+ -+#define USB_EVENT_DELAY_TIM 1000 -+ -+/************************************** -+** Write Bulk Out Check Time(ms) -+**************************************/ -+ -+#define WR_BULKOUT_CHK_TIM 1000 -+ -+/************************************** -+** Media Check Time(ms) -+**************************************/ -+ -+#define MEDIA_CHECK_TIM 3000 -+#define MEDIA_CHECK_RETRY 3 -+ -+/************************************** -+** Context -+**************************************/ -+ -+#define CONTEXT_SCHEDULE 0 -+#define CONTEXT_STORAGE 1 -+#define CONTEXT_TIMER 2 -+ -+/************************************** -+** Debug Message -+**************************************/ -+#if 0 -+#define DBG_STORAGE_FD(fmt, args...) printk(fmt, ##args) -+#else -+#define DBG_STORAGE_FD(fmt, args...) -+#endif -+ -+/****************************************************************************** -+** Structure Define -+******************************************************************************/ -+ -+/************************************** -+** Command Block Wrapper / Command Status Wrapper -+**************************************/ -+ -+/* -+ * Command Block Wrapper -+ */ -+typedef struct{ -+ unsigned long dCBWSignature; -+ unsigned long dCBWTag; -+ unsigned long dCBWDataTransferLength; -+ unsigned char bmCBWFlags; -+ unsigned char bCBWLUN:4, -+ Reserved:4; -+ unsigned char bCBWCBLength:5, -+ Reserved2:3; -+ unsigned char CBWCB[16]; -+} __attribute__((packed)) COMMAND_BLOCK_WRAPPER; -+ -+/* -+ * Command Status Wrapper -+ */ -+typedef struct{ -+ unsigned long dCSWSignature; -+ unsigned long dCSWTag; -+ unsigned long dCSWDataResidue; -+ unsigned char bCSWStatus; -+} __attribute__((packed)) COMMAND_STATUS_WRAPPER; -+ -+/************************************** -+** SCSI Command -+**************************************/ -+ -+/* -+ * INQUIRY -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char EVPD:1, -+ Reserved1:4, -+ LogicalUnitNumber:3; -+ unsigned char PageCode; -+ unsigned char Reserved2; -+ unsigned char AllocationLength; -+ unsigned char Reserved3; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+} __attribute__((packed)) SCSI_INQUIRY_COMMAND; -+ -+typedef struct{ -+ unsigned char PeripheralDeviceType:5, -+ Reserved1:3; -+ unsigned char Reserved2:7, -+ RMB:1; -+ unsigned char ANSIVersion:3, -+ ECMAVersion:3, -+ ISOVersion:2; -+ unsigned char ResponseDataFormat:4, -+ Reserved3:4; -+ unsigned char AdditionalLength; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char VendorInformation[8]; -+ unsigned char ProductIdentification[16]; -+ unsigned char ProductRevisionLevel[4]; -+} __attribute__((packed)) SCSI_INQUIRY_DATA; -+ -+/* -+ * READ FORMAT CAPACITY -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char Reserved1:5, -+ LogicalUnitNumber:3; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char AllocationLength[2]; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+} __attribute__((packed)) SCSI_READ_FORMAT_CAPACITY_COMMAND; -+ -+typedef struct{ -+ struct{ -+ unsigned char Reserved1; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char CapacityListLength; -+ } __attribute__((packed)) CapacityListHeader; -+ struct{ -+ unsigned char NumberofBlocks[4]; -+ unsigned char DescriptorCode:2, -+ Reserved1:6; -+ unsigned char BlockLength[3]; -+ } __attribute__((packed)) CurrentMaximumCapacityDescriptor; -+} __attribute__((packed)) SCSI_READ_FORMAT_CAPACITY_DATA; -+ -+/* -+ * READ FORMAT CAPACITY -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char RelAdr:1, -+ Reserved1:4, -+ LogicalUnitNumber:3; -+ unsigned char LogicalBlockAddress[4]; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char PMI:1, -+ Reserved4:7; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+} __attribute__((packed)) SCSI_READ_CAPACITY_COMMAND; -+ -+typedef struct{ -+ unsigned char LastLogicalBlockAddress[4]; -+ unsigned char BlockLengthInBytes[4]; -+} __attribute__((packed)) SCSI_READ_CAPACITY_DATA; -+ -+/* -+ * REQUEST SENSE -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char Reserved1:5, -+ LogicalUnitNumber:3; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char AllocationLength; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+ unsigned char Reserved10; -+} __attribute__((packed)) SCSI_REQUEST_SENSE_COMMAND; -+ -+typedef struct{ -+ unsigned char ErrorCode:7, -+ Valid:1; -+ unsigned char Reserved1; -+ unsigned char SenseKey:4, -+ Reserved2:4; -+ unsigned char Information[4]; -+ unsigned char AdditionalSenseLength; -+ unsigned char Reserved3[4]; -+ unsigned char AdditionalSenseCode; -+ unsigned char AdditionalSenseCodeQualifier; -+ unsigned char Reserved4; -+ unsigned char Reserved5[3]; -+} __attribute__((packed)) SCSI_REQUEST_SENSE_DATA; -+ -+/* -+ * READ(10) -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char RelAdr:1, -+ Reserved1:2, -+ FUA:1, -+ DPO:1, -+ LogicalUnitNumber:3; -+ unsigned char LogicalBlockAddress[4]; -+ unsigned char Reserved2; -+ unsigned char TransferLength[2]; -+ unsigned char Reserved3; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+} __attribute__((packed)) SCSI_READ_10_COMMAND; -+ -+/* -+ * MODE SENSE -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char Reserved1:3, -+ DBD:1, -+ Reserved2:1, -+ LogicalUnitNumber:3; -+ unsigned char PageCode:6, -+ PC:2; -+ unsigned char Reserved3; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char ParameterListLength[2]; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+} __attribute__((packed)) SCSI_MODE_SENSE_COMMAND; -+ -+typedef struct{ -+ unsigned char ModeDataLength; -+ unsigned char MediumTypeCode; -+ unsigned char Reserved1:4, -+ DPOFUA:1, -+ Reserved2:2, -+ WP:1; -+ unsigned char Reserved3; -+} __attribute__((packed)) MODE_PARAMETER_HEADER; -+ -+typedef struct{ -+ unsigned char PageCode:6, -+ Reserved1:1, -+ PS:1; -+ unsigned char PageLength; -+ unsigned char DCR:1, -+ Reserved2:1, -+ PER:1, -+ Reserved3:1, -+ RC:1, -+ Reserved4:1, -+ Reserved5:1, -+ AWRE:1; -+ unsigned char ReadRetryCount; -+ unsigned char Reserved6[4]; -+ unsigned char WriteRetryCount; -+ unsigned char Reserved7[3]; -+} __attribute__((packed)) READ_WRITE_ERROR_RECOVERY_PAGE; -+ -+typedef struct{ -+ unsigned char PageCode:6, -+ Reserved1:1, -+ PS:1; -+ unsigned char PageLength; -+ unsigned char TransferRate[2]; -+ unsigned char NumberofHeads; -+ unsigned char SectorsperTrack; -+ unsigned char DataBytesperSector[2]; -+ unsigned char NumberofCylinders[2]; -+ unsigned char Reserved2[9]; -+ unsigned char MotorOnDelay; -+ unsigned char MotorOffDelay; -+ unsigned char Reserved3[7]; -+ unsigned char MediumRotationRate[2]; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+} __attribute__((packed)) FLEXIBLE_DISK_PAGE; -+ -+typedef struct{ -+ unsigned char PageCode:6, -+ Reserved1:1, -+ PS:1; -+ unsigned char PageLength; -+ unsigned char Reserved2:6, -+ SRFP:1, -+ SFLP:1; -+ unsigned char TLUN:3, -+ Reserved3:3, -+ SML:1, -+ NCD:1; -+ unsigned char Reserved4[8]; -+} __attribute__((packed)) REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE; -+ -+typedef struct{ -+ unsigned char PageCode:6, -+ Reserved1:1, -+ PS:1; -+ unsigned char PageLength; -+ unsigned char Reserved2; -+ unsigned char InactivityTimeMultiplier:4, -+ Reserved3:4; -+ unsigned char SWPP:1, -+ DISP:1, -+ Reserved4:6; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+} __attribute__((packed)) TIMER_AND_PROTECT_PAGE; -+ -+typedef struct{ -+ READ_WRITE_ERROR_RECOVERY_PAGE ReadWriteErrorRecoveryPage; -+ FLEXIBLE_DISK_PAGE FlexibleDiskPage; -+ REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE RemovableBlockAccessCapabilitiesPage; -+ TIMER_AND_PROTECT_PAGE TimerAndProtectPage; -+} __attribute__((packed)) MODE_ALL_PAGES; -+ -+typedef struct{ -+ MODE_PARAMETER_HEADER ModeParameterHeader; -+ union{ -+ READ_WRITE_ERROR_RECOVERY_PAGE ReadWriteErrorRecoveryPage; -+ FLEXIBLE_DISK_PAGE FlexibleDiskPage; -+ REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE RemovableBlockAccessCapabilitiesPage; -+ TIMER_AND_PROTECT_PAGE TimerAndProtectPage; -+ MODE_ALL_PAGES ModeAllPages; -+ } __attribute__((packed)) ModePages; -+} __attribute__((packed)) SCSI_MODE_SENSE_DATA; -+ -+/* -+ * TEST UNIT READY -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char Reserved1:5, -+ LogicalUnitNumber:3; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+ unsigned char Reserved10; -+ unsigned char Reserved11; -+} __attribute__((packed)) SCSI_TEST_UNIT_READY_COMMAND; -+ -+/* -+ * PREVENT-ALLOW MEDIUM REMOVAL -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char Reserved1:5, -+ LogicalUnitNumber:3; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char Prevent:1, -+ Reserved4:7; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+ unsigned char Reserved10; -+ unsigned char Reserved11; -+} __attribute__((packed)) SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL_COMMAND; -+ -+/* -+ * START-STOP UNIT -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char IMMED:1, -+ Reserved1:4, -+ LogicalUnitNumber:3; -+ unsigned char Reserved2; -+ unsigned char Reserved3; -+ unsigned char Start:1, -+ LoEj:1, -+ Reserved4:6; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+ unsigned char Reserved7; -+ unsigned char Reserved8; -+ unsigned char Reserved9; -+ unsigned char Reserved10; -+ unsigned char Reserved11; -+} __attribute__((packed)) SCSI_START_STOP_COMMAND; -+ -+/* -+ * WRITE(10) -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char RelAdr:1, -+ Reserved1:2, -+ FUA:1, -+ DPO:1, -+ LogicalUnitNumber:3; -+ unsigned char LogicalBlockAddress[4]; -+ unsigned char Reserved2; -+ unsigned char TransferLength[2]; -+ unsigned char Reserved3; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+} __attribute__((packed)) SCSI_WRITE_10_COMMAND; -+ -+/* -+ * VERIFY -+ */ -+ -+typedef struct{ -+ unsigned char OperationCode; -+ unsigned char RelAdr:1, -+ ByteChk:1, -+ Reserved1:1, -+ Reserved2:1, -+ DPO:1, -+ LogicalUnitNumber:3; -+ unsigned char LogicalBlockAddress[4]; -+ unsigned char Reserved3; -+ unsigned char VerificationLength[2]; -+ unsigned char Reserved4; -+ unsigned char Reserved5; -+ unsigned char Reserved6; -+} __attribute__((packed)) SCSI_VERIFY_COMMAND; -+ -+/****************************************************************************** -+** Global Function Prototype -+******************************************************************************/ -+ -+/* storage-fd.c */ -+void storage_urb_send(struct usb_device_instance*, void*, int); -+ -+/* storageproto.c */ -+void storageproto_urb_analysis(struct urb*); -+int storageproto_device_open_check(void); -+void storageproto_device_close(void); -+void storageproto_usb_status_check(int); -+void storageproto_media_status_check(int); -+void storageproto_usb_reset_ind(void); -+ssize_t storageproto_proc_read(struct file*, char*, size_t, loff_t* pos); -+void storageproto_init(void); -+void storageproto_exit(void); -+ -+#endif /* _STORAGEPROTO_H_ */ -+ |