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