1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
/* Header file for the hpusbscsi driver */
/* (C) Copyright 2001 Oliver Neukum */
/* sponsored by the Linux Usb Project */
/* large parts based on or taken from code by John Fremlin and Matt Dharm */
/* this file is licensed under the GPL */
typedef void (*usb_urb_callback) (struct urb *);
typedef void (*scsi_callback)(Scsi_Cmnd *);
struct hpusbscsi
{
struct list_head lh;
struct usb_device *dev; /* NULL indicates unplugged device */
int ep_out;
int ep_in;
int ep_int;
int interrupt_interval;
struct Scsi_Host *host;
Scsi_Host_Template ctempl;
int number;
scsi_callback scallback;
Scsi_Cmnd *srb;
int use_count;
wait_queue_head_t pending;
wait_queue_head_t deathrow;
struct urb dataurb;
struct urb controlurb;
int fragment;
int state;
int current_data_pipe;
u8 scsi_state_byte;
};
#define SCSI_ERR_MASK ~0x3fu
static const unsigned char scsi_command_direction[256/8] = {
0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#define DIRECTION_IS_IN(x) ((scsi_command_direction[x>>3] >> (x & 7)) & 1)
static int hpusbscsi_scsi_detect (struct SHT * sht);
static void simple_command_callback(struct urb *u);
static void scatter_gather_callback(struct urb *u);
static void simple_payload_callback (struct urb *u);
static void control_interrupt_callback (struct urb *u);
static void simple_done (struct urb *u);
static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
static Scsi_Host_Template hpusbscsi_scsi_host_template = {
name: "hpusbscsi",
detect: hpusbscsi_scsi_detect,
// release: hpusbscsi_scsi_release,
queuecommand: hpusbscsi_scsi_queuecommand,
eh_abort_handler: hpusbscsi_scsi_abort,
eh_host_reset_handler: hpusbscsi_scsi_host_reset,
sg_tablesize: SG_ALL,
can_queue: 1,
this_id: -1,
cmd_per_lun: 1,
present: 0,
unchecked_isa_dma: FALSE,
use_clustering: TRUE,
use_new_eh_code: TRUE,
emulated: TRUE
};
/* defines for internal driver state */
#define HP_STATE_FREE 0 /*ready for next request */
#define HP_STATE_BEGINNING 1 /*command being transfered */
#define HP_STATE_WORKING 2 /* data transfer stage */
#define HP_STATE_ERROR 3 /* error has been reported */
#define HP_STATE_WAIT 4 /* waiting for status transfer */
#define HP_STATE_PREMATURE 5 /* status prematurely reported */
|