# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.551 -> 1.552 # drivers/usb/hpusbscsi.h 1.4 -> 1.5 # drivers/usb/hpusbscsi.c 1.9 -> 1.10 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/03/19 oliver@oenone.homelinux.org 1.552 # USB hpusbscsi driver # # Port changes from 2.4: # We do request_sense ourselves to comply with # the scanner command set # -------------------------------------------- # diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c --- a/drivers/usb/hpusbscsi.c Wed Apr 3 16:39:56 2002 +++ b/drivers/usb/hpusbscsi.c Wed Apr 3 16:39:56 2002 @@ -129,6 +129,9 @@ if (scsi_register_host(&new->ctempl)) goto err_out; + new->sense_command[0] = REQUEST_SENSE; + new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH; + /* adding to list for module unload */ list_add (&hpusbscsi_devices, &new->lh); @@ -379,6 +382,7 @@ static void control_interrupt_callback (struct urb *u) { struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context; + u8 scsi_state; DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte); if(unlikely(u->status < 0)) { @@ -386,10 +390,23 @@ handle_usb_error(hpusbscsi); return; } - hpusbscsi->srb->result &= SCSI_ERR_MASK; - hpusbscsi->srb->result |= hpusbscsi->scsi_state_byte; - if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT) + scsi_state = hpusbscsi->scsi_state_byte; + if (hpusbscsi->state != HP_STATE_ERROR) { + hpusbscsi->srb->result &= SCSI_ERR_MASK; + hpusbscsi->srb->result |= scsi_state; + } + + if (scsi_state == CHECK_CONDITION << 1) { + if (hpusbscsi->state == HP_STATE_WAIT) { + issue_request_sense(hpusbscsi); + } else { + /* we request sense after an eventual data transfer */ + hpusbscsi->state = HP_STATE_ERROR; + } + } + + if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT && scsi_state != CHECK_CONDITION <<1 ) /* we do a callback to the scsi layer if and only if all data has been transfered */ hpusbscsi->scallback(hpusbscsi->srb); @@ -404,6 +421,8 @@ hpusbscsi->state = HP_STATE_PREMATURE; TRACE_STATE; break; + case HP_STATE_ERROR: + break; default: printk(KERN_ERR"hpusbscsi: Unexpected status report.\n"); TRACE_STATE; @@ -432,32 +451,6 @@ } } -static void request_sense_callback (struct urb *u) -{ - struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context; - - if (unlikely(u->status<0)) { - handle_usb_error(hpusbscsi); - return; - } - - FILL_BULK_URB( - u, - hpusbscsi->dev, - hpusbscsi->current_data_pipe, - hpusbscsi->srb->sense_buffer, - SCSI_SENSE_BUFFERSIZE, - simple_done, - hpusbscsi - ); - - if (unlikely(0 > usb_submit_urb(u, GFP_ATOMIC))) { - handle_usb_error(hpusbscsi); - return; - } - hpusbscsi->state = HP_STATE_WORKING; -} - static void scatter_gather_callback(struct urb *u) { struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context; @@ -494,7 +487,7 @@ res = usb_submit_urb(u, GFP_ATOMIC); if (unlikely(res)) - hpusbscsi->state = HP_STATE_ERROR; + handle_usb_error(hpusbscsi); TRACE_STATE; } @@ -509,11 +502,15 @@ DEBUG("Data transfer done\n"); TRACE_STATE; if (hpusbscsi->state != HP_STATE_PREMATURE) { - if (unlikely(u->status < 0)) - hpusbscsi->state = HP_STATE_ERROR; - else - hpusbscsi->state = HP_STATE_WAIT; - TRACE_STATE; + if (unlikely(u->status < 0)) { + handle_usb_error(hpusbscsi); + } else { + if (hpusbscsi->state != HP_STATE_ERROR) { + hpusbscsi->state = HP_STATE_WAIT; + } else { + issue_request_sense(hpusbscsi); + } + } } else { if (likely(hpusbscsi->scallback != NULL)) hpusbscsi->scallback(hpusbscsi->srb); @@ -550,12 +547,52 @@ if (hpusbscsi->state != HP_STATE_PREMATURE) { hpusbscsi->state = HP_STATE_WORKING; TRACE_STATE; - } else { - if (likely(hpusbscsi->scallback != NULL)) - hpusbscsi->scallback(hpusbscsi->srb); - hpusbscsi->state = HP_STATE_FREE; - TRACE_STATE; + } +} + +static void request_sense_callback (struct urb *u) +{ + struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context; + + if (u->status<0) { + handle_usb_error(hpusbscsi); + return; + } + + FILL_BULK_URB( + u, + hpusbscsi->dev, + hpusbscsi->current_data_pipe, + hpusbscsi->srb->sense_buffer, + SCSI_SENSE_BUFFERSIZE, + simple_done, + hpusbscsi + ); + + if (0 > usb_submit_urb(u, GFP_ATOMIC)) { + handle_usb_error(hpusbscsi); + return; } + if (hpusbscsi->state != HP_STATE_PREMATURE && hpusbscsi->state != HP_STATE_ERROR) + hpusbscsi->state = HP_STATE_WORKING; } +static void issue_request_sense (struct hpusbscsi *hpusbscsi) +{ + FILL_BULK_URB( + hpusbscsi->dataurb, + hpusbscsi->dev, + usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out), + &hpusbscsi->sense_command, + SENSE_COMMAND_SIZE, + request_sense_callback, + hpusbscsi + ); + + hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in); + + if (0 > usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC)) { + handle_usb_error(hpusbscsi); + } +} diff -Nru a/drivers/usb/hpusbscsi.h b/drivers/usb/hpusbscsi.h --- a/drivers/usb/hpusbscsi.h Wed Apr 3 16:39:56 2002 +++ b/drivers/usb/hpusbscsi.h Wed Apr 3 16:39:56 2002 @@ -4,9 +4,14 @@ /* large parts based on or taken from code by John Fremlin and Matt Dharm */ /* this file is licensed under the GPL */ +/* A big thanks to Jose for untiring testing */ + typedef void (*usb_urb_callback) (struct urb *); typedef void (*scsi_callback)(Scsi_Cmnd *); +#define SENSE_COMMAND_SIZE 6 +#define HPUSBSCSI_SENSE_LENGTH 0x16 + struct hpusbscsi { struct list_head lh; @@ -19,8 +24,9 @@ struct Scsi_Host *host; Scsi_Host_Template ctempl; int number; - scsi_callback scallback; - Scsi_Cmnd *srb; + scsi_callback scallback; + Scsi_Cmnd *srb; + u8 sense_command[SENSE_COMMAND_SIZE]; int use_count; wait_queue_head_t pending; @@ -57,6 +63,7 @@ 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 void issue_request_sense (struct hpusbscsi *hpusbscsi); static Scsi_Host_Template hpusbscsi_scsi_host_template = { name: "hpusbscsi", @@ -84,5 +91,6 @@ #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 */ +