| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* Driver for USB Mass Storage compliant devices | 
|  | 2 | * Main Header File | 
|  | 3 | * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 4 | * Current development and maintenance by: | 
|  | 5 | *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) | 
|  | 6 | * | 
|  | 7 | * Initial work by: | 
|  | 8 | *   (c) 1999 Michael Gee (michael@linuxspecific.com) | 
|  | 9 | * | 
|  | 10 | * This driver is based on the 'USB Mass Storage Class' document. This | 
|  | 11 | * describes in detail the protocol used to communicate with such | 
|  | 12 | * devices.  Clearly, the designers had SCSI and ATAPI commands in | 
|  | 13 | * mind when they created this document.  The commands are all very | 
|  | 14 | * similar to commands in the SCSI-II and ATAPI specifications. | 
|  | 15 | * | 
|  | 16 | * It is important to note that in a number of cases this class | 
|  | 17 | * exhibits class-specific exemptions from the USB specification. | 
|  | 18 | * Notably the usage of NAK, STALL and ACK differs from the norm, in | 
|  | 19 | * that they are used to communicate wait, failed and OK on commands. | 
|  | 20 | * | 
|  | 21 | * Also, for certain devices, the interrupt endpoint is used to convey | 
|  | 22 | * status of a command. | 
|  | 23 | * | 
|  | 24 | * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more | 
|  | 25 | * information about this driver. | 
|  | 26 | * | 
|  | 27 | * This program is free software; you can redistribute it and/or modify it | 
|  | 28 | * under the terms of the GNU General Public License as published by the | 
|  | 29 | * Free Software Foundation; either version 2, or (at your option) any | 
|  | 30 | * later version. | 
|  | 31 | * | 
|  | 32 | * This program is distributed in the hope that it will be useful, but | 
|  | 33 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | 35 | * General Public License for more details. | 
|  | 36 | * | 
|  | 37 | * You should have received a copy of the GNU General Public License along | 
|  | 38 | * with this program; if not, write to the Free Software Foundation, Inc., | 
|  | 39 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | 40 | */ | 
|  | 41 |  | 
|  | 42 | #ifndef _USB_H_ | 
|  | 43 | #define _USB_H_ | 
|  | 44 |  | 
|  | 45 | #include <linux/usb.h> | 
| Pete Zaitcev | a00828e | 2005-10-22 20:15:09 -0700 | [diff] [blame] | 46 | #include <linux/usb_usual.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 | #include <linux/blkdev.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 48 | #include <linux/completion.h> | 
| Arjan van de Ven | 4186ecf | 2006-01-11 15:55:29 +0100 | [diff] [blame] | 49 | #include <linux/mutex.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | #include <scsi/scsi_host.h> | 
|  | 51 |  | 
|  | 52 | struct us_data; | 
|  | 53 | struct scsi_cmnd; | 
|  | 54 |  | 
|  | 55 | /* | 
|  | 56 | * Unusual device list definitions | 
|  | 57 | */ | 
|  | 58 |  | 
|  | 59 | struct us_unusual_dev { | 
|  | 60 | const char* vendorName; | 
|  | 61 | const char* productName; | 
|  | 62 | __u8  useProtocol; | 
|  | 63 | __u8  useTransport; | 
|  | 64 | int (*initFunction)(struct us_data *); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 65 | }; | 
|  | 66 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 |  | 
| Alan Stern | 7e4d6c3 | 2008-05-01 15:35:18 -0400 | [diff] [blame] | 68 | /* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */ | 
|  | 69 | #define US_FLIDX_URB_ACTIVE	0	/* current_urb is in use    */ | 
|  | 70 | #define US_FLIDX_SG_ACTIVE	1	/* current_sg is in use     */ | 
|  | 71 | #define US_FLIDX_ABORTING	2	/* abort is in progress     */ | 
|  | 72 | #define US_FLIDX_DISCONNECTING	3	/* disconnect in progress   */ | 
| Alan Stern | 7e4d6c3 | 2008-05-01 15:35:18 -0400 | [diff] [blame] | 73 | #define US_FLIDX_RESETTING	4	/* device reset in progress */ | 
|  | 74 | #define US_FLIDX_TIMED_OUT	5	/* SCSI midlayer timed out  */ | 
| Alan Stern | 543f781 | 2008-05-08 11:55:59 -0400 | [diff] [blame] | 75 | #define US_FLIDX_DONT_SCAN	6	/* don't scan (disconnect)  */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 |  | 
|  | 77 | #define USB_STOR_STRING_LEN 32 | 
|  | 78 |  | 
|  | 79 | /* | 
|  | 80 | * We provide a DMA-mapped I/O buffer for use with small USB transfers. | 
|  | 81 | * It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a | 
|  | 82 | * 31-byte buffer.  But Freecom needs a 64-byte buffer, so that's the | 
|  | 83 | * size we'll allocate. | 
|  | 84 | */ | 
|  | 85 |  | 
|  | 86 | #define US_IOBUF_SIZE		64	/* Size of the DMA-mapped I/O buffer */ | 
| Alan Stern | bbafa46 | 2005-10-23 19:40:22 -0700 | [diff] [blame] | 87 | #define US_SENSE_SIZE		18	/* Size of the autosense data buffer */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 |  | 
|  | 89 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); | 
|  | 90 | typedef int (*trans_reset)(struct us_data*); | 
|  | 91 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); | 
| Matthew Dharm | 7931e1c | 2005-12-04 21:56:51 -0800 | [diff] [blame] | 92 | typedef void (*extra_data_destructor)(void *);	/* extra data destructor */ | 
|  | 93 | typedef void (*pm_hook)(struct us_data *, int);	/* power management hook */ | 
|  | 94 |  | 
|  | 95 | #define US_SUSPEND	0 | 
|  | 96 | #define US_RESUME	1 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 97 |  | 
|  | 98 | /* we allocate one of these for every device that we remember */ | 
|  | 99 | struct us_data { | 
|  | 100 | /* The device we're working with | 
|  | 101 | * It's important to note: | 
| Arjan van de Ven | 4186ecf | 2006-01-11 15:55:29 +0100 | [diff] [blame] | 102 | *    (o) you must hold dev_mutex to change pusb_dev | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 103 | */ | 
| Arjan van de Ven | 4186ecf | 2006-01-11 15:55:29 +0100 | [diff] [blame] | 104 | struct mutex		dev_mutex;	 /* protect pusb_dev */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 105 | struct usb_device	*pusb_dev;	 /* this usb_device */ | 
|  | 106 | struct usb_interface	*pusb_intf;	 /* this interface */ | 
|  | 107 | struct us_unusual_dev   *unusual_dev;	 /* device-filter entry     */ | 
| Alan Stern | 7e4d6c3 | 2008-05-01 15:35:18 -0400 | [diff] [blame] | 108 | unsigned long		fflags;		 /* fixed flags from filter */ | 
|  | 109 | unsigned long		dflags;		 /* dynamic atomic bitflags */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 110 | unsigned int		send_bulk_pipe;	 /* cached pipe values */ | 
|  | 111 | unsigned int		recv_bulk_pipe; | 
|  | 112 | unsigned int		send_ctrl_pipe; | 
|  | 113 | unsigned int		recv_ctrl_pipe; | 
|  | 114 | unsigned int		recv_intr_pipe; | 
|  | 115 |  | 
|  | 116 | /* information about the device */ | 
|  | 117 | char			*transport_name; | 
|  | 118 | char			*protocol_name; | 
|  | 119 | __le32			bcs_signature; | 
|  | 120 | u8			subclass; | 
|  | 121 | u8			protocol; | 
|  | 122 | u8			max_lun; | 
|  | 123 |  | 
|  | 124 | u8			ifnum;		 /* interface number   */ | 
|  | 125 | u8			ep_bInterval;	 /* interrupt interval */ | 
|  | 126 |  | 
|  | 127 | /* function pointers for this device */ | 
|  | 128 | trans_cmnd		transport;	 /* transport function	   */ | 
|  | 129 | trans_reset		transport_reset; /* transport device reset */ | 
|  | 130 | proto_cmnd		proto_handler;	 /* protocol handler	   */ | 
|  | 131 |  | 
|  | 132 | /* SCSI interfaces */ | 
|  | 133 | struct scsi_cmnd	*srb;		 /* current srb		*/ | 
| Matthew Dharm | 0f64e07 | 2005-07-28 14:43:08 -0700 | [diff] [blame] | 134 | unsigned int		tag;		 /* current dCBWTag	*/ | 
| Matthew Wilcox | 00fa43e | 2009-09-24 16:19:11 -0600 | [diff] [blame] | 135 | char			scsi_name[32];	 /* scsi_host name	*/ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 136 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 137 | /* control and bulk communications data */ | 
|  | 138 | struct urb		*current_urb;	 /* USB requests	 */ | 
|  | 139 | struct usb_ctrlrequest	*cr;		 /* control requests	 */ | 
|  | 140 | struct usb_sg_request	current_sg;	 /* scatter-gather req.  */ | 
|  | 141 | unsigned char		*iobuf;		 /* I/O buffer		 */ | 
| Alan Stern | 0ede76f | 2010-03-05 15:10:17 -0500 | [diff] [blame] | 142 | dma_addr_t		iobuf_dma;	 /* buffer DMA addresses */ | 
| Alan Stern | ed76cac | 2007-06-07 17:12:25 -0400 | [diff] [blame] | 143 | struct task_struct	*ctl_thread;	 /* the control thread   */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 144 |  | 
|  | 145 | /* mutual exclusion and synchronization structures */ | 
| Alan Stern | 7119e3c | 2008-05-01 15:36:13 -0400 | [diff] [blame] | 146 | struct completion	cmnd_ready;	 /* to sleep thread on	    */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 147 | struct completion	notify;		 /* thread begin/end	    */ | 
|  | 148 | wait_queue_head_t	delay_wait;	 /* wait during scan, reset */ | 
| Alan Stern | 2f67cd5 | 2007-08-16 16:16:00 -0400 | [diff] [blame] | 149 | struct completion	scanning_done;	 /* wait for scan thread    */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 150 |  | 
|  | 151 | /* subdriver information */ | 
|  | 152 | void			*extra;		 /* Any extra data          */ | 
|  | 153 | extra_data_destructor	extra_destructor;/* extra data destructor   */ | 
| Matthew Dharm | 7931e1c | 2005-12-04 21:56:51 -0800 | [diff] [blame] | 154 | #ifdef CONFIG_PM | 
|  | 155 | pm_hook			suspend_resume_hook; | 
|  | 156 | #endif | 
| Alan Stern | 25ff1c3 | 2008-12-15 12:43:41 -0500 | [diff] [blame] | 157 |  | 
|  | 158 | /* hacks for READ CAPACITY bug handling */ | 
|  | 159 | int			use_last_sector_hacks; | 
|  | 160 | int			last_sector_retries; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 161 | }; | 
|  | 162 |  | 
|  | 163 | /* Convert between us_data and the corresponding Scsi_Host */ | 
| Jesper Juhl | f274afc | 2006-06-26 19:01:01 +0200 | [diff] [blame] | 164 | static inline struct Scsi_Host *us_to_host(struct us_data *us) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 165 | return container_of((void *) us, struct Scsi_Host, hostdata); | 
|  | 166 | } | 
| Jesper Juhl | f274afc | 2006-06-26 19:01:01 +0200 | [diff] [blame] | 167 | static inline struct us_data *host_to_us(struct Scsi_Host *host) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 168 | return (struct us_data *) host->hostdata; | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | /* Function to fill an inquiry response. See usb.c for details */ | 
|  | 172 | extern void fill_inquiry_response(struct us_data *us, | 
|  | 173 | unsigned char *data, unsigned int data_len); | 
|  | 174 |  | 
|  | 175 | /* The scsi_lock() and scsi_unlock() macros protect the sm_state and the | 
|  | 176 | * single queue element srb for write access */ | 
|  | 177 | #define scsi_unlock(host)	spin_unlock_irq(host->host_lock) | 
|  | 178 | #define scsi_lock(host)		spin_lock_irq(host->host_lock) | 
|  | 179 |  | 
| Alan Stern | e6e244b | 2009-02-12 14:47:44 -0500 | [diff] [blame] | 180 | /* General routines provided by the usb-storage standard core */ | 
|  | 181 | #ifdef CONFIG_PM | 
|  | 182 | extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message); | 
|  | 183 | extern int usb_stor_resume(struct usb_interface *iface); | 
|  | 184 | extern int usb_stor_reset_resume(struct usb_interface *iface); | 
|  | 185 | #else | 
|  | 186 | #define usb_stor_suspend	NULL | 
|  | 187 | #define usb_stor_resume		NULL | 
|  | 188 | #define usb_stor_reset_resume	NULL | 
|  | 189 | #endif | 
|  | 190 |  | 
|  | 191 | extern int usb_stor_pre_reset(struct usb_interface *iface); | 
|  | 192 | extern int usb_stor_post_reset(struct usb_interface *iface); | 
|  | 193 |  | 
|  | 194 | extern int usb_stor_probe1(struct us_data **pus, | 
|  | 195 | struct usb_interface *intf, | 
|  | 196 | const struct usb_device_id *id, | 
|  | 197 | struct us_unusual_dev *unusual_dev); | 
|  | 198 | extern int usb_stor_probe2(struct us_data *us); | 
|  | 199 | extern void usb_stor_disconnect(struct usb_interface *intf); | 
|  | 200 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 201 | #endif |