2005-04-17 00:20:36 +02:00
|
|
|
/* Driver for USB Mass Storage compliant devices
|
|
|
|
* Main Header File
|
|
|
|
*
|
|
|
|
* Current development and maintenance by:
|
|
|
|
* (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
|
|
|
|
*
|
|
|
|
* Initial work by:
|
|
|
|
* (c) 1999 Michael Gee (michael@linuxspecific.com)
|
|
|
|
*
|
|
|
|
* This driver is based on the 'USB Mass Storage Class' document. This
|
|
|
|
* describes in detail the protocol used to communicate with such
|
|
|
|
* devices. Clearly, the designers had SCSI and ATAPI commands in
|
|
|
|
* mind when they created this document. The commands are all very
|
|
|
|
* similar to commands in the SCSI-II and ATAPI specifications.
|
|
|
|
*
|
|
|
|
* It is important to note that in a number of cases this class
|
|
|
|
* exhibits class-specific exemptions from the USB specification.
|
|
|
|
* Notably the usage of NAK, STALL and ACK differs from the norm, in
|
|
|
|
* that they are used to communicate wait, failed and OK on commands.
|
|
|
|
*
|
|
|
|
* Also, for certain devices, the interrupt endpoint is used to convey
|
|
|
|
* status of a command.
|
|
|
|
*
|
|
|
|
* Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
|
|
|
|
* information about this driver.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
* later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _USB_H_
|
|
|
|
#define _USB_H_
|
|
|
|
|
|
|
|
#include <linux/usb.h>
|
2005-10-23 05:15:09 +02:00
|
|
|
#include <linux/usb_usual.h>
|
2005-04-17 00:20:36 +02:00
|
|
|
#include <linux/blkdev.h>
|
|
|
|
#include <linux/completion.h>
|
2006-01-11 15:55:29 +01:00
|
|
|
#include <linux/mutex.h>
|
2005-04-17 00:20:36 +02:00
|
|
|
#include <scsi/scsi_host.h>
|
|
|
|
|
|
|
|
struct us_data;
|
|
|
|
struct scsi_cmnd;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unusual device list definitions
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct us_unusual_dev {
|
|
|
|
const char* vendorName;
|
|
|
|
const char* productName;
|
|
|
|
__u8 useProtocol;
|
|
|
|
__u8 useTransport;
|
|
|
|
int (*initFunction)(struct us_data *);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-05-01 21:35:18 +02:00
|
|
|
/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
|
|
|
|
#define US_FLIDX_URB_ACTIVE 0 /* current_urb is in use */
|
|
|
|
#define US_FLIDX_SG_ACTIVE 1 /* current_sg is in use */
|
|
|
|
#define US_FLIDX_ABORTING 2 /* abort is in progress */
|
|
|
|
#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */
|
|
|
|
#define US_FLIDX_RESETTING 4 /* device reset in progress */
|
|
|
|
#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
|
2008-05-08 17:55:59 +02:00
|
|
|
#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
#define USB_STOR_STRING_LEN 32
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We provide a DMA-mapped I/O buffer for use with small USB transfers.
|
|
|
|
* It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a
|
|
|
|
* 31-byte buffer. But Freecom needs a 64-byte buffer, so that's the
|
|
|
|
* size we'll allocate.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */
|
2005-10-24 04:40:22 +02:00
|
|
|
#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
|
|
|
|
typedef int (*trans_reset)(struct us_data*);
|
|
|
|
typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
|
2005-12-05 06:56:51 +01:00
|
|
|
typedef void (*extra_data_destructor)(void *); /* extra data destructor */
|
|
|
|
typedef void (*pm_hook)(struct us_data *, int); /* power management hook */
|
|
|
|
|
|
|
|
#define US_SUSPEND 0
|
|
|
|
#define US_RESUME 1
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/* we allocate one of these for every device that we remember */
|
|
|
|
struct us_data {
|
|
|
|
/* The device we're working with
|
|
|
|
* It's important to note:
|
2006-01-11 15:55:29 +01:00
|
|
|
* (o) you must hold dev_mutex to change pusb_dev
|
2005-04-17 00:20:36 +02:00
|
|
|
*/
|
2006-01-11 15:55:29 +01:00
|
|
|
struct mutex dev_mutex; /* protect pusb_dev */
|
2005-04-17 00:20:36 +02:00
|
|
|
struct usb_device *pusb_dev; /* this usb_device */
|
|
|
|
struct usb_interface *pusb_intf; /* this interface */
|
|
|
|
struct us_unusual_dev *unusual_dev; /* device-filter entry */
|
2008-05-01 21:35:18 +02:00
|
|
|
unsigned long fflags; /* fixed flags from filter */
|
|
|
|
unsigned long dflags; /* dynamic atomic bitflags */
|
2005-04-17 00:20:36 +02:00
|
|
|
unsigned int send_bulk_pipe; /* cached pipe values */
|
|
|
|
unsigned int recv_bulk_pipe;
|
|
|
|
unsigned int send_ctrl_pipe;
|
|
|
|
unsigned int recv_ctrl_pipe;
|
|
|
|
unsigned int recv_intr_pipe;
|
|
|
|
|
|
|
|
/* information about the device */
|
|
|
|
char *transport_name;
|
|
|
|
char *protocol_name;
|
|
|
|
__le32 bcs_signature;
|
|
|
|
u8 subclass;
|
|
|
|
u8 protocol;
|
|
|
|
u8 max_lun;
|
|
|
|
|
|
|
|
u8 ifnum; /* interface number */
|
|
|
|
u8 ep_bInterval; /* interrupt interval */
|
|
|
|
|
|
|
|
/* function pointers for this device */
|
|
|
|
trans_cmnd transport; /* transport function */
|
|
|
|
trans_reset transport_reset; /* transport device reset */
|
|
|
|
proto_cmnd proto_handler; /* protocol handler */
|
|
|
|
|
|
|
|
/* SCSI interfaces */
|
|
|
|
struct scsi_cmnd *srb; /* current srb */
|
2005-07-28 23:43:08 +02:00
|
|
|
unsigned int tag; /* current dCBWTag */
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/* control and bulk communications data */
|
|
|
|
struct urb *current_urb; /* USB requests */
|
|
|
|
struct usb_ctrlrequest *cr; /* control requests */
|
|
|
|
struct usb_sg_request current_sg; /* scatter-gather req. */
|
|
|
|
unsigned char *iobuf; /* I/O buffer */
|
|
|
|
dma_addr_t cr_dma; /* buffer DMA addresses */
|
|
|
|
dma_addr_t iobuf_dma;
|
2007-06-07 23:12:25 +02:00
|
|
|
struct task_struct *ctl_thread; /* the control thread */
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/* mutual exclusion and synchronization structures */
|
2008-05-01 21:36:13 +02:00
|
|
|
struct completion cmnd_ready; /* to sleep thread on */
|
2005-04-17 00:20:36 +02:00
|
|
|
struct completion notify; /* thread begin/end */
|
|
|
|
wait_queue_head_t delay_wait; /* wait during scan, reset */
|
2007-08-16 22:16:00 +02:00
|
|
|
struct completion scanning_done; /* wait for scan thread */
|
2005-04-17 00:20:36 +02:00
|
|
|
|
|
|
|
/* subdriver information */
|
|
|
|
void *extra; /* Any extra data */
|
|
|
|
extra_data_destructor extra_destructor;/* extra data destructor */
|
2005-12-05 06:56:51 +01:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
pm_hook suspend_resume_hook;
|
|
|
|
#endif
|
USB: storage: add last-sector hacks
This patch (as1189b) adds some hacks to usb-storage for dealing with
the growing problems involving bad capacity values and last-sector
accesses:
A new flag, US_FL_CAPACITY_OK, is created to indicate that
the device is known to report its capacity correctly. An
unusual_devs entry for Linux's own File-backed Storage Gadget
is added with this flag set, since g_file_storage always
reports the correct capacity and since the capacity need
not be even (it is determined by the size of the backing
file).
An entry in unusual_devs.h which has only the CAPACITY_OK
flag set shouldn't prejudice libusual, since the device will
work perfectly well with either usb-storage or ub. So a
new macro, COMPLIANT_DEV, is added to let libusual know
about these entries.
When a last-sector access succeeds and the total number of
sectors is odd (the unexpected case, in which guessing that
the number is even might cause trouble), a WARN is triggered.
The kerneloops.org project will collect these warnings,
allowing us to add CAPACITY_OK flags for the devices in
question before implementing the default-to-even heuristic.
If users want to prevent the stack dump produced by the WARN,
they can disable the hack by adding an unusual_devs entry
for their device with the CAPACITY_OK flag.
When a last-sector access fails three times in a row and
neither the FIX_CAPACITY nor the CAPACITY_OK flag is set,
we assume the last-sector bug is present. We replace the
existing status and sense data with values that will cause
the SCSI core to fail the access immediately rather than
retry indefinitely. This should fix the difficulties
people have been having with Nokia phones.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2008-12-15 18:43:41 +01:00
|
|
|
|
|
|
|
/* hacks for READ CAPACITY bug handling */
|
|
|
|
int use_last_sector_hacks;
|
|
|
|
int last_sector_retries;
|
2005-04-17 00:20:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Convert between us_data and the corresponding Scsi_Host */
|
2006-06-26 19:01:01 +02:00
|
|
|
static inline struct Scsi_Host *us_to_host(struct us_data *us) {
|
2005-04-17 00:20:36 +02:00
|
|
|
return container_of((void *) us, struct Scsi_Host, hostdata);
|
|
|
|
}
|
2006-06-26 19:01:01 +02:00
|
|
|
static inline struct us_data *host_to_us(struct Scsi_Host *host) {
|
2005-04-17 00:20:36 +02:00
|
|
|
return (struct us_data *) host->hostdata;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Function to fill an inquiry response. See usb.c for details */
|
|
|
|
extern void fill_inquiry_response(struct us_data *us,
|
|
|
|
unsigned char *data, unsigned int data_len);
|
|
|
|
|
|
|
|
/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
|
|
|
|
* single queue element srb for write access */
|
|
|
|
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
|
|
|
|
#define scsi_lock(host) spin_lock_irq(host->host_lock)
|
|
|
|
|
usb-storage: prepare for subdriver separation
This patch (as1206) is the first step in converting usb-storage's
subdrivers into separate modules. It makes the following large-scale
changes:
Remove a bunch of unnecessary #ifdef's from usb_usual.h.
Not truly necessary, but it does clean things up.
Move the USB device-ID table (which is duplicated between
libusual and usb-storage) into its own source file,
usual-tables.c, and arrange for this to be linked with
either libusual or usb-storage according to whether
USB_LIBUSUAL is configured.
Add to usual-tables.c a new usb_usual_ignore_device()
function to detect whether a particular device needs to be
managed by a subdriver and not by the standard handlers
in usb-storage.
Export a whole bunch of functions in usb-storage, renaming
some of them because their names don't already begin with
"usb_stor_". These functions will be needed by the new
subdriver modules.
Split usb-storage's probe routine into two functions.
The subdrivers will call the probe1 routine, then fill in
their transport and protocol settings, and then call the
probe2 routine.
Take the default cases and error checking out of
get_transport() and get_protocol(), which run during
probe1, and instead put a check for invalid transport
or protocol values into the probe2 function.
Add a new probe routine to be used for standard devices,
i.e., those that don't need a subdriver. This new routine
checks whether the device should be ignored (because it
should be handled by ub or by a subdriver), and if not,
calls the probe1 and probe2 functions.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-02-12 20:47:44 +01:00
|
|
|
/* General routines provided by the usb-storage standard core */
|
|
|
|
#ifdef CONFIG_PM
|
|
|
|
extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message);
|
|
|
|
extern int usb_stor_resume(struct usb_interface *iface);
|
|
|
|
extern int usb_stor_reset_resume(struct usb_interface *iface);
|
|
|
|
#else
|
|
|
|
#define usb_stor_suspend NULL
|
|
|
|
#define usb_stor_resume NULL
|
|
|
|
#define usb_stor_reset_resume NULL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern int usb_stor_pre_reset(struct usb_interface *iface);
|
|
|
|
extern int usb_stor_post_reset(struct usb_interface *iface);
|
|
|
|
|
|
|
|
extern int usb_stor_probe1(struct us_data **pus,
|
|
|
|
struct usb_interface *intf,
|
|
|
|
const struct usb_device_id *id,
|
|
|
|
struct us_unusual_dev *unusual_dev);
|
|
|
|
extern int usb_stor_probe2(struct us_data *us);
|
|
|
|
extern void usb_stor_disconnect(struct usb_interface *intf);
|
|
|
|
|
2005-04-17 00:20:36 +02:00
|
|
|
#endif
|