1
2
3
4
5
6
7
8
9typedef void (*usb_urb_callback) (struct urb *);
10typedef void (*scsi_callback)(Scsi_Cmnd *);
11
12#define SENSE_COMMAND_SIZE 6
13#define HPUSBSCSI_SENSE_LENGTH 0x16
14
15struct hpusbscsi
16{
17 struct list_head lh;
18 struct usb_device *dev;
19 int ep_out;
20 int ep_in;
21 int ep_int;
22 int interrupt_interval;
23 int need_short_workaround;
24
25 struct Scsi_Host *host;
26 Scsi_Host_Template ctempl;
27 int number;
28 scsi_callback scallback;
29 Scsi_Cmnd *srb;
30 u8 sense_command[SENSE_COMMAND_SIZE];
31
32 int use_count;
33 struct semaphore lock;
34 wait_queue_head_t pending;
35 wait_queue_head_t deathrow;
36
37 struct urb dataurb;
38 struct urb controlurb;
39 int fragment;
40
41 int state;
42 int current_data_pipe;
43
44 u8 scsi_state_byte;
45};
46
47#define SCSI_ERR_MASK ~0x3fu
48
49static const unsigned char scsi_command_direction[256/8] = {
50 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
51 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
54};
55
56#define DIRECTION_IS_IN(x) ((scsi_command_direction[x>>3] >> (x & 7)) & 1)
57
58static int hpusbscsi_scsi_detect (struct SHT * sht);
59static void simple_command_callback(struct urb *u);
60static void scatter_gather_callback(struct urb *u);
61static void simple_payload_callback (struct urb *u);
62static void control_interrupt_callback (struct urb *u);
63static void request_sense_callback (struct urb *u);
64static void simple_done (struct urb *u);
65static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
66static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
67static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
68static void issue_request_sense (struct hpusbscsi *hpusbscsi);
69
70static Scsi_Host_Template hpusbscsi_scsi_host_template = {
71 name: "hpusbscsi",
72 detect: hpusbscsi_scsi_detect,
73
74 queuecommand: hpusbscsi_scsi_queuecommand,
75
76 eh_abort_handler: hpusbscsi_scsi_abort,
77 eh_host_reset_handler: hpusbscsi_scsi_host_reset,
78
79 sg_tablesize: SG_ALL,
80 can_queue: 1,
81 this_id: -1,
82 cmd_per_lun: 1,
83 present: 0,
84 unchecked_isa_dma: FALSE,
85 use_clustering: TRUE,
86 use_new_eh_code: TRUE,
87 emulated: TRUE
88};
89
90
91#define HP_STATE_FREE 0
92#define HP_STATE_BEGINNING 1
93#define HP_STATE_WORKING 2
94#define HP_STATE_ERROR 3
95#define HP_STATE_WAIT 4
96#define HP_STATE_PREMATURE 5
97
98
99