162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Driver for USB Mass Storage compliant devices
462306a36Sopenharmony_ci * Main Header File
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Current development and maintenance by:
762306a36Sopenharmony_ci *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Initial work by:
1062306a36Sopenharmony_ci *   (c) 1999 Michael Gee (michael@linuxspecific.com)
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * This driver is based on the 'USB Mass Storage Class' document. This
1362306a36Sopenharmony_ci * describes in detail the protocol used to communicate with such
1462306a36Sopenharmony_ci * devices.  Clearly, the designers had SCSI and ATAPI commands in
1562306a36Sopenharmony_ci * mind when they created this document.  The commands are all very
1662306a36Sopenharmony_ci * similar to commands in the SCSI-II and ATAPI specifications.
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * It is important to note that in a number of cases this class
1962306a36Sopenharmony_ci * exhibits class-specific exemptions from the USB specification.
2062306a36Sopenharmony_ci * Notably the usage of NAK, STALL and ACK differs from the norm, in
2162306a36Sopenharmony_ci * that they are used to communicate wait, failed and OK on commands.
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * Also, for certain devices, the interrupt endpoint is used to convey
2462306a36Sopenharmony_ci * status of a command.
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#ifndef _USB_H_
2862306a36Sopenharmony_ci#define _USB_H_
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <linux/usb.h>
3162306a36Sopenharmony_ci#include <linux/usb_usual.h>
3262306a36Sopenharmony_ci#include <linux/blkdev.h>
3362306a36Sopenharmony_ci#include <linux/completion.h>
3462306a36Sopenharmony_ci#include <linux/mutex.h>
3562306a36Sopenharmony_ci#include <linux/workqueue.h>
3662306a36Sopenharmony_ci#include <scsi/scsi_host.h>
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistruct us_data;
3962306a36Sopenharmony_cistruct scsi_cmnd;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/*
4262306a36Sopenharmony_ci * Unusual device list definitions
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct us_unusual_dev {
4662306a36Sopenharmony_ci	const char* vendorName;
4762306a36Sopenharmony_ci	const char* productName;
4862306a36Sopenharmony_ci	__u8  useProtocol;
4962306a36Sopenharmony_ci	__u8  useTransport;
5062306a36Sopenharmony_ci	int (*initFunction)(struct us_data *);
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
5562306a36Sopenharmony_ci#define US_FLIDX_URB_ACTIVE	0	/* current_urb is in use    */
5662306a36Sopenharmony_ci#define US_FLIDX_SG_ACTIVE	1	/* current_sg is in use     */
5762306a36Sopenharmony_ci#define US_FLIDX_ABORTING	2	/* abort is in progress     */
5862306a36Sopenharmony_ci#define US_FLIDX_DISCONNECTING	3	/* disconnect in progress   */
5962306a36Sopenharmony_ci#define US_FLIDX_RESETTING	4	/* device reset in progress */
6062306a36Sopenharmony_ci#define US_FLIDX_TIMED_OUT	5	/* SCSI midlayer timed out  */
6162306a36Sopenharmony_ci#define US_FLIDX_SCAN_PENDING	6	/* scanning not yet done    */
6262306a36Sopenharmony_ci#define US_FLIDX_REDO_READ10	7	/* redo READ(10) command    */
6362306a36Sopenharmony_ci#define US_FLIDX_READ10_WORKED	8	/* previous READ(10) succeeded */
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#define USB_STOR_STRING_LEN 32
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci/*
6862306a36Sopenharmony_ci * We provide a DMA-mapped I/O buffer for use with small USB transfers.
6962306a36Sopenharmony_ci * It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a
7062306a36Sopenharmony_ci * 31-byte buffer.  But Freecom needs a 64-byte buffer, so that's the
7162306a36Sopenharmony_ci * size we'll allocate.
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#define US_IOBUF_SIZE		64	/* Size of the DMA-mapped I/O buffer */
7562306a36Sopenharmony_ci#define US_SENSE_SIZE		18	/* Size of the autosense data buffer */
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_citypedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
7862306a36Sopenharmony_citypedef int (*trans_reset)(struct us_data*);
7962306a36Sopenharmony_citypedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
8062306a36Sopenharmony_citypedef void (*extra_data_destructor)(void *);	/* extra data destructor */
8162306a36Sopenharmony_citypedef void (*pm_hook)(struct us_data *, int);	/* power management hook */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#define US_SUSPEND	0
8462306a36Sopenharmony_ci#define US_RESUME	1
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* we allocate one of these for every device that we remember */
8762306a36Sopenharmony_cistruct us_data {
8862306a36Sopenharmony_ci	/*
8962306a36Sopenharmony_ci	 * The device we're working with
9062306a36Sopenharmony_ci	 * It's important to note:
9162306a36Sopenharmony_ci	 *    (o) you must hold dev_mutex to change pusb_dev
9262306a36Sopenharmony_ci	 */
9362306a36Sopenharmony_ci	struct mutex		dev_mutex;	 /* protect pusb_dev */
9462306a36Sopenharmony_ci	struct usb_device	*pusb_dev;	 /* this usb_device */
9562306a36Sopenharmony_ci	struct usb_interface	*pusb_intf;	 /* this interface */
9662306a36Sopenharmony_ci	const struct us_unusual_dev   *unusual_dev;
9762306a36Sopenharmony_ci						/* device-filter entry     */
9862306a36Sopenharmony_ci	unsigned long		fflags;		 /* fixed flags from filter */
9962306a36Sopenharmony_ci	unsigned long		dflags;		 /* dynamic atomic bitflags */
10062306a36Sopenharmony_ci	unsigned int		send_bulk_pipe;	 /* cached pipe values */
10162306a36Sopenharmony_ci	unsigned int		recv_bulk_pipe;
10262306a36Sopenharmony_ci	unsigned int		send_ctrl_pipe;
10362306a36Sopenharmony_ci	unsigned int		recv_ctrl_pipe;
10462306a36Sopenharmony_ci	unsigned int		recv_intr_pipe;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	/* information about the device */
10762306a36Sopenharmony_ci	char			*transport_name;
10862306a36Sopenharmony_ci	char			*protocol_name;
10962306a36Sopenharmony_ci	__le32			bcs_signature;
11062306a36Sopenharmony_ci	u8			subclass;
11162306a36Sopenharmony_ci	u8			protocol;
11262306a36Sopenharmony_ci	u8			max_lun;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	u8			ifnum;		 /* interface number   */
11562306a36Sopenharmony_ci	u8			ep_bInterval;	 /* interrupt interval */
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	/* function pointers for this device */
11862306a36Sopenharmony_ci	trans_cmnd		transport;	 /* transport function	   */
11962306a36Sopenharmony_ci	trans_reset		transport_reset; /* transport device reset */
12062306a36Sopenharmony_ci	proto_cmnd		proto_handler;	 /* protocol handler	   */
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	/* SCSI interfaces */
12362306a36Sopenharmony_ci	struct scsi_cmnd	*srb;		 /* current srb		*/
12462306a36Sopenharmony_ci	unsigned int		tag;		 /* current dCBWTag	*/
12562306a36Sopenharmony_ci	char			scsi_name[32];	 /* scsi_host name	*/
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	/* control and bulk communications data */
12862306a36Sopenharmony_ci	struct urb		*current_urb;	 /* USB requests	 */
12962306a36Sopenharmony_ci	struct usb_ctrlrequest	*cr;		 /* control requests	 */
13062306a36Sopenharmony_ci	struct usb_sg_request	current_sg;	 /* scatter-gather req.  */
13162306a36Sopenharmony_ci	unsigned char		*iobuf;		 /* I/O buffer		 */
13262306a36Sopenharmony_ci	dma_addr_t		iobuf_dma;	 /* buffer DMA addresses */
13362306a36Sopenharmony_ci	struct task_struct	*ctl_thread;	 /* the control thread   */
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/* mutual exclusion and synchronization structures */
13662306a36Sopenharmony_ci	struct completion	cmnd_ready;	 /* to sleep thread on	    */
13762306a36Sopenharmony_ci	struct completion	notify;		 /* thread begin/end	    */
13862306a36Sopenharmony_ci	wait_queue_head_t	delay_wait;	 /* wait during reset	    */
13962306a36Sopenharmony_ci	struct delayed_work	scan_dwork;	 /* for async scanning      */
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	/* subdriver information */
14262306a36Sopenharmony_ci	void			*extra;		 /* Any extra data          */
14362306a36Sopenharmony_ci	extra_data_destructor	extra_destructor;/* extra data destructor   */
14462306a36Sopenharmony_ci#ifdef CONFIG_PM
14562306a36Sopenharmony_ci	pm_hook			suspend_resume_hook;
14662306a36Sopenharmony_ci#endif
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	/* hacks for READ CAPACITY bug handling */
14962306a36Sopenharmony_ci	int			use_last_sector_hacks;
15062306a36Sopenharmony_ci	int			last_sector_retries;
15162306a36Sopenharmony_ci};
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/* Convert between us_data and the corresponding Scsi_Host */
15462306a36Sopenharmony_cistatic inline struct Scsi_Host *us_to_host(struct us_data *us) {
15562306a36Sopenharmony_ci	return container_of((void *) us, struct Scsi_Host, hostdata);
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_cistatic inline struct us_data *host_to_us(struct Scsi_Host *host) {
15862306a36Sopenharmony_ci	return (struct us_data *) host->hostdata;
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/* Function to fill an inquiry response. See usb.c for details */
16262306a36Sopenharmony_ciextern void fill_inquiry_response(struct us_data *us,
16362306a36Sopenharmony_ci	unsigned char *data, unsigned int data_len);
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci/*
16662306a36Sopenharmony_ci * The scsi_lock() and scsi_unlock() macros protect the sm_state and the
16762306a36Sopenharmony_ci * single queue element srb for write access
16862306a36Sopenharmony_ci */
16962306a36Sopenharmony_ci#define scsi_unlock(host)	spin_unlock_irq(host->host_lock)
17062306a36Sopenharmony_ci#define scsi_lock(host)		spin_lock_irq(host->host_lock)
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/* General routines provided by the usb-storage standard core */
17362306a36Sopenharmony_ci#ifdef CONFIG_PM
17462306a36Sopenharmony_ciextern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message);
17562306a36Sopenharmony_ciextern int usb_stor_resume(struct usb_interface *iface);
17662306a36Sopenharmony_ciextern int usb_stor_reset_resume(struct usb_interface *iface);
17762306a36Sopenharmony_ci#else
17862306a36Sopenharmony_ci#define usb_stor_suspend	NULL
17962306a36Sopenharmony_ci#define usb_stor_resume		NULL
18062306a36Sopenharmony_ci#define usb_stor_reset_resume	NULL
18162306a36Sopenharmony_ci#endif
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ciextern int usb_stor_pre_reset(struct usb_interface *iface);
18462306a36Sopenharmony_ciextern int usb_stor_post_reset(struct usb_interface *iface);
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciextern int usb_stor_probe1(struct us_data **pus,
18762306a36Sopenharmony_ci		struct usb_interface *intf,
18862306a36Sopenharmony_ci		const struct usb_device_id *id,
18962306a36Sopenharmony_ci		const struct us_unusual_dev *unusual_dev,
19062306a36Sopenharmony_ci		const struct scsi_host_template *sht);
19162306a36Sopenharmony_ciextern int usb_stor_probe2(struct us_data *us);
19262306a36Sopenharmony_ciextern void usb_stor_disconnect(struct usb_interface *intf);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciextern void usb_stor_adjust_quirks(struct usb_device *dev,
19562306a36Sopenharmony_ci		unsigned long *fflags);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci#define module_usb_stor_driver(__driver, __sht, __name) \
19862306a36Sopenharmony_cistatic int __init __driver##_init(void) \
19962306a36Sopenharmony_ci{ \
20062306a36Sopenharmony_ci	usb_stor_host_template_init(&(__sht), __name, THIS_MODULE); \
20162306a36Sopenharmony_ci	return usb_register(&(__driver)); \
20262306a36Sopenharmony_ci} \
20362306a36Sopenharmony_cimodule_init(__driver##_init); \
20462306a36Sopenharmony_cistatic void __exit __driver##_exit(void) \
20562306a36Sopenharmony_ci{ \
20662306a36Sopenharmony_ci	usb_deregister(&(__driver)); \
20762306a36Sopenharmony_ci} \
20862306a36Sopenharmony_cimodule_exit(__driver##_exit)
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci#endif
211