linux-old/drivers/usb/hpusbscsi.c
<<
>>
Prefs
   1/*
   2 * hpusbscsi
   3 * (C) Copyright 2001 Oliver Neukum 
   4 * Sponsored by the Linux Usb Project
   5 * Large parts based on or taken from code by John Fremlin and Matt Dharm
   6 * 
   7 * This driver is known to work with the following scanners (VID, PID)
   8 *    (0x03f0, 0x0701)  HP 53xx 
   9 *    (0x03f0, 0x0801)  HP 7400 
  10 *    (0x0638, 0x026a)  Minolta Scan Dual II
  11 *    (0x0686, 0x4004)  Minolta Elite II
  12 * To load with full debugging load with "insmod hpusbscsi debug=2"
  13 * 
  14 * This program is free software; you can redistribute it and/or modify it
  15 * under the terms of the GNU General Public License as published by the
  16 * Free Software Foundation; either version 2 of the License, or (at your
  17 * option) any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful, but
  20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  21 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  22 * for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, write to the Free Software Foundation,
  26 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27 *
  28 * Contributors:
  29 *   Oliver Neukum
  30 *   John Fremlin
  31 *   Matt Dharm
  32 *   .
  33 *   .
  34 *   Timothy Jedlicka <bonzo@lucent.com>
  35 *
  36 * History
  37 *
  38 * 22-Apr-2002
  39 *
  40 * - Added Elite II scanner - bonzo
  41 * - Cleaned up the debug statements and made them optional at load time - bonzo
  42 *
  43 * 20020618
  44 *
  45 * - Confirm to stupid 2.4 rules on io_request_lock
  46 *
  47 */
  48
  49#include <linux/module.h>
  50#include <linux/kernel.h>
  51#include <linux/sched.h>
  52#include <linux/signal.h>
  53#include <linux/errno.h>
  54#include <linux/init.h>
  55#include <linux/slab.h>
  56#include <linux/spinlock.h>
  57#include <linux/smp_lock.h>
  58#include <linux/usb.h>
  59#include <asm/atomic.h>
  60#include <linux/blk.h>
  61#include "../scsi/scsi.h"
  62#include "../scsi/hosts.h"
  63#include "../scsi/sd.h"
  64
  65#include "hpusbscsi.h"
  66
  67static char *states[]={"FREE", "BEGINNING", "WORKING", "ERROR", "WAIT", "PREMATURE"};
  68
  69/* DEBUG related parts */
  70#define HPUSBSCSI_DEBUG
  71
  72#ifdef HPUSBSCSI_DEBUG
  73#  define PDEBUG(level, fmt, args...) \
  74          if (debug >= (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , \
  75                 ## args)
  76#else
  77#  define PDEBUG(level, fmt, args...) do {} while(0)
  78#endif
  79
  80
  81/* 0=no debug messages
  82 * 1=everything but trace states
  83 * 2=trace states
  84 */
  85static int debug; /* = 0 */
  86
  87MODULE_PARM(debug, "i");
  88MODULE_PARM_DESC(debug, "Debug level: 0=none, 1=no trace states, 2=trace states");
  89
  90/* global variables */
  91
  92struct list_head hpusbscsi_devices;
  93//LIST_HEAD(hpusbscsi_devices);
  94
  95/* USB related parts */
  96
  97static void *
  98hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface,
  99                     const struct usb_device_id *id)
 100{
 101        struct hpusbscsi *new;
 102        struct usb_interface_descriptor *altsetting =
 103                &(dev->actconfig->interface[interface].altsetting[0]);
 104
 105        int i, result;
 106
 107        /* basic check */
 108
 109        if (altsetting->bNumEndpoints != 3) {
 110                printk (KERN_ERR "Wrong number of endpoints\n");
 111                return NULL;
 112        }
 113
 114        /* descriptor allocation */
 115
 116        new =
 117                (struct hpusbscsi *) kmalloc (sizeof (struct hpusbscsi),
 118                                              GFP_KERNEL);
 119        if (new == NULL)
 120                return NULL;
 121        PDEBUG (1, "Allocated memory");
 122        memset (new, 0, sizeof (struct hpusbscsi));
 123        spin_lock_init (&new->dataurb.lock);
 124        spin_lock_init (&new->controlurb.lock);
 125        new->dev = dev;
 126        init_waitqueue_head (&new->pending);
 127        init_waitqueue_head (&new->deathrow);
 128        init_MUTEX(&new->lock);
 129        INIT_LIST_HEAD (&new->lh);
 130        
 131        if (id->idVendor == 0x0686 && id->idProduct == 0x4004)
 132                new->need_short_workaround = 1;
 133
 134
 135
 136        /* finding endpoints */
 137
 138        for (i = 0; i < altsetting->bNumEndpoints; i++) {
 139                if (
 140                    (altsetting->endpoint[i].
 141                     bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 142                    USB_ENDPOINT_XFER_BULK) {
 143                        if (altsetting->endpoint[i].
 144                            bEndpointAddress & USB_DIR_IN) {
 145                                new->ep_in =
 146                                        altsetting->endpoint[i].
 147                                        bEndpointAddress &
 148                                        USB_ENDPOINT_NUMBER_MASK;
 149                        } else {
 150                                new->ep_out =
 151                                        altsetting->endpoint[i].
 152                                        bEndpointAddress &
 153                                        USB_ENDPOINT_NUMBER_MASK;
 154                        }
 155                } else {
 156                        new->ep_int =
 157                                altsetting->endpoint[i].
 158                                bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 159                        new->interrupt_interval= altsetting->endpoint[i].bInterval;
 160                }
 161        }
 162
 163        /* USB initialisation magic for the simple case */
 164
 165        result = usb_set_interface (dev, altsetting->bInterfaceNumber, 0);
 166
 167        switch (result) {
 168        case 0:         /* no error */
 169                break;
 170
 171        case -EPIPE:
 172                usb_clear_halt (dev, usb_sndctrlpipe (dev, 0));
 173                break;
 174
 175        default:
 176                printk (KERN_ERR "unknown error %d from usb_set_interface\n",
 177                         result);
 178                goto err_out;
 179        }
 180
 181        /* making a template for the scsi layer to fake detection of a scsi device */
 182
 183        memcpy (&(new->ctempl), &hpusbscsi_scsi_host_template,
 184                sizeof (hpusbscsi_scsi_host_template));
 185        new->ctempl.proc_dir = (void *) new;
 186        new->ctempl.module = THIS_MODULE;
 187
 188        if (scsi_register_module (MODULE_SCSI_HA, &(new->ctempl)))
 189                goto err_out;
 190
 191        new->sense_command[0] = REQUEST_SENSE;
 192        new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
 193
 194        /* adding to list for module unload */
 195        list_add (&hpusbscsi_devices, &new->lh);
 196
 197        return new;
 198
 199      err_out:
 200        kfree (new);
 201        return NULL;
 202}
 203
 204static void
 205hpusbscsi_usb_disconnect (struct usb_device *dev, void *ptr)
 206{
 207        struct hpusbscsi *hp = (struct hpusbscsi *)ptr;
 208
 209        down(&hp->lock);
 210        usb_unlink_urb(&hp->controlurb);
 211        usb_unlink_urb(&hp->dataurb);
 212
 213        hp->dev = NULL;
 214        up(&hp->lock);
 215}
 216
 217static struct usb_device_id hpusbscsi_usb_ids[] = {
 218        {USB_DEVICE (0x03f0, 0x0701)},  /* HP 53xx */
 219        {USB_DEVICE (0x03f0, 0x0801)},  /* HP 7400 */
 220        {USB_DEVICE (0x0638, 0x0268)},  /*iVina 1200U */
 221        {USB_DEVICE (0x0638, 0x026a)},  /*Scan Dual II */
 222        {USB_DEVICE (0x0638, 0x0A13)},  /*Avision AV600U */
 223        {USB_DEVICE (0x0638, 0x0A16)},  /*Avision DS610CU Scancopier */
 224        {USB_DEVICE (0x0638, 0x0A18)},  /*Avision AV600U Plus */
 225        {USB_DEVICE (0x0638, 0x0A23)},  /*Avision AV220 */
 226        {USB_DEVICE (0x0638, 0x0A24)},  /*Avision AV210 */
 227        {USB_DEVICE (0x0686, 0x4004)},  /*Minolta Elite II */
 228        {}                      /* Terminating entry */
 229};
 230
 231MODULE_DEVICE_TABLE (usb, hpusbscsi_usb_ids);
 232MODULE_LICENSE("GPL");
 233
 234
 235static struct usb_driver hpusbscsi_usb_driver = {
 236        name:"hpusbscsi",
 237        probe:hpusbscsi_usb_probe,
 238        disconnect:hpusbscsi_usb_disconnect,
 239        id_table:hpusbscsi_usb_ids,
 240};
 241
 242/* module initialisation */
 243
 244int __init
 245hpusbscsi_init (void)
 246{
 247        int result;
 248
 249        INIT_LIST_HEAD (&hpusbscsi_devices);
 250        PDEBUG(0, "driver loaded, DebugLvel=%d", debug);
 251 
 252        if ((result = usb_register (&hpusbscsi_usb_driver)) < 0) {
 253                printk (KERN_ERR "hpusbscsi: driver registration failed\n");
 254                return -1;
 255        } else {
 256                return 0;
 257        }
 258}
 259
 260void __exit
 261hpusbscsi_exit (void)
 262{
 263        struct list_head *tmp;
 264        struct list_head *old;
 265        struct hpusbscsi * o;
 266
 267        for (tmp = hpusbscsi_devices.next; tmp != &hpusbscsi_devices;/*nothing */) {
 268                old = tmp;
 269                tmp = tmp->next;
 270                o = (struct hpusbscsi *)old;
 271                usb_unlink_urb(&o->controlurb);
 272                if(scsi_unregister_module(MODULE_SCSI_HA,&o->ctempl)<0)
 273                        printk(KERN_CRIT"Deregistering failed!\n");
 274                kfree(old);
 275        }
 276
 277        usb_deregister (&hpusbscsi_usb_driver);
 278}
 279
 280module_init (hpusbscsi_init);
 281module_exit (hpusbscsi_exit);
 282
 283/* interface to the scsi layer */
 284
 285static int
 286hpusbscsi_scsi_detect (struct SHT *sht)
 287{
 288        /* Whole function stolen from usb-storage */
 289
 290        struct hpusbscsi *desc = (struct hpusbscsi *) sht->proc_dir;
 291        /* What a hideous hack! */
 292
 293        char local_name[48];
 294        spin_unlock_irq(&io_request_lock);
 295
 296
 297        /* set up the name of our subdirectory under /proc/scsi/ */
 298        sprintf (local_name, "hpusbscsi-%d", desc->number);
 299        sht->proc_name = kmalloc (strlen (local_name) + 1, GFP_KERNEL);
 300        /* FIXME: where is this freed ? */
 301
 302        if (!sht->proc_name) {
 303                spin_lock_irq(&io_request_lock);
 304                return 0;
 305        }
 306
 307        strcpy (sht->proc_name, local_name);
 308
 309        sht->proc_dir = NULL;
 310
 311        /* build and submit an interrupt URB for status byte handling */
 312        FILL_INT_URB(&desc->controlurb,
 313                        desc->dev,
 314                        usb_rcvintpipe(desc->dev,desc->ep_int),
 315                        &desc->scsi_state_byte,
 316                        1,
 317                        control_interrupt_callback,
 318                        desc,
 319                        desc->interrupt_interval
 320        );
 321
 322        if ( 0  >  usb_submit_urb(&desc->controlurb)) {
 323                kfree(sht->proc_name);
 324                spin_lock_irq(&io_request_lock);
 325                return 0;
 326        }
 327
 328        /* In host->hostdata we store a pointer to desc */
 329        desc->host = scsi_register (sht, sizeof (desc));
 330        if (desc->host == NULL) {
 331                kfree (sht->proc_name);
 332                usb_unlink_urb(&desc->controlurb);
 333                spin_lock_irq(&io_request_lock);
 334                return 0;
 335        }
 336        desc->host->hostdata[0] = (unsigned long) desc;
 337        spin_lock_irq(&io_request_lock);
 338
 339        return 1;
 340}
 341
 342static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
 343{
 344        struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
 345        usb_urb_callback usb_callback;
 346        int res, passed_length;
 347
 348        spin_unlock_irq(&io_request_lock);
 349
 350        /* we don't answer for anything but our single device on any faked host controller */
 351        if ( srb->device->lun || srb->device->id || srb->device->channel ) {
 352                srb->result = DID_BAD_TARGET;
 353                callback(srb);
 354                goto out_nolock;
 355        }
 356
 357        /* to prevent a race with removal */
 358        down(&hpusbscsi->lock);
 359
 360        if (hpusbscsi->dev == NULL) {
 361                srb->result = DID_ERROR;
 362                callback(srb);
 363                goto out;
 364        }
 365        
 366        /* otto fix - the Scan Elite II has a 5 second
 367        * delay anytime the srb->cmd_len=6
 368        * This causes it to run very slowly unless we
 369        * pad the command length to 10 */
 370        
 371        if (hpusbscsi -> need_short_workaround && srb->cmd_len < 10) {
 372                memset(srb->cmnd + srb->cmd_len, 0, 10 - srb->cmd_len);
 373                passed_length = 10;
 374        } else {
 375                passed_length = srb->cmd_len;
 376        }
 377        
 378
 379        /* Now we need to decide which callback to give to the urb we send the command with */
 380
 381        if (!srb->bufflen) {
 382                if (srb->cmnd[0] == REQUEST_SENSE){
 383                        /* the usual buffer is not used, needs a special case */
 384                        hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
 385                        usb_callback = request_sense_callback;
 386                } else {
 387                        usb_callback = simple_command_callback;
 388                }
 389        } else {
 390                if (srb->use_sg) {
 391                        usb_callback = scatter_gather_callback;
 392                        hpusbscsi->fragment = 0;
 393                } else {
 394                        usb_callback = simple_payload_callback;
 395                }
 396                /* Now we find out which direction data is to be transfered in */
 397                hpusbscsi->current_data_pipe = DIRECTION_IS_IN(srb->cmnd[0]) ?
 398                        usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in)
 399                :
 400                        usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out)
 401                ;
 402        }
 403
 404
 405        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 406        if (hpusbscsi->state != HP_STATE_FREE) {
 407                printk(KERN_CRIT"hpusbscsi - Ouch: queueing violation!\n");
 408                return 1; /* This must not happen */
 409        }
 410
 411        /* We zero the sense buffer to avoid confusing user space */
 412        memset(srb->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 413
 414        hpusbscsi->state = HP_STATE_BEGINNING;
 415        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 416
 417        /* We prepare the urb for writing out the scsi command */
 418        FILL_BULK_URB(
 419                &hpusbscsi->dataurb,
 420                hpusbscsi->dev,
 421                usb_sndbulkpipe(hpusbscsi->dev,hpusbscsi->ep_out),
 422                srb->cmnd,
 423                passed_length,
 424                usb_callback,
 425                hpusbscsi
 426        );
 427        hpusbscsi->scallback = callback;
 428        hpusbscsi->srb = srb;
 429
 430
 431        res = usb_submit_urb(&hpusbscsi->dataurb);
 432        if (res) {
 433                hpusbscsi->state = HP_STATE_FREE;
 434                PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 435                srb->result = DID_ERROR;
 436                callback(srb);
 437
 438        }
 439
 440out:
 441        up(&hpusbscsi->lock);
 442out_nolock:
 443        spin_lock_irq(&io_request_lock);
 444        return 0;
 445}
 446
 447static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb)
 448{
 449        struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
 450
 451        PDEBUG(1, "SCSI reset requested");
 452        //usb_reset_device(hpusbscsi->dev);
 453        //PDEBUG(1, "SCSI reset completed");
 454        hpusbscsi->state = HP_STATE_FREE;
 455
 456        return 0;
 457}
 458
 459static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
 460{
 461        struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
 462        PDEBUG(1, "Request is canceled");
 463
 464        spin_unlock_irq(&io_request_lock);
 465        usb_unlink_urb(&hpusbscsi->dataurb);
 466        hpusbscsi->state = HP_STATE_FREE;
 467
 468        spin_lock_irq(&io_request_lock);
 469
 470        return SCSI_ABORT_PENDING;
 471}
 472
 473/* usb interrupt handlers - they are all running IN INTERRUPT ! */
 474
 475static void handle_usb_error (struct hpusbscsi *hpusbscsi)
 476{
 477        if (hpusbscsi->scallback != NULL) {
 478                hpusbscsi->srb->result = DID_ERROR;
 479                hpusbscsi->scallback(hpusbscsi->srb);
 480        }
 481        hpusbscsi->state = HP_STATE_FREE;
 482}
 483
 484static void  control_interrupt_callback (struct urb *u)
 485{
 486        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 487        u8 scsi_state;
 488
 489        PDEBUG(1, "Getting status byte %d",hpusbscsi->scsi_state_byte);
 490        if(u->status < 0) {
 491                if (hpusbscsi->state != HP_STATE_FREE)
 492                        handle_usb_error(hpusbscsi);
 493                return;
 494        }
 495
 496        scsi_state = hpusbscsi->scsi_state_byte;
 497        if (hpusbscsi->state != HP_STATE_ERROR) {
 498                hpusbscsi->srb->result &= SCSI_ERR_MASK;
 499                hpusbscsi->srb->result |= scsi_state;
 500        }
 501
 502        if (scsi_state == CHECK_CONDITION << 1) {
 503                if (hpusbscsi->state == HP_STATE_WAIT) {
 504                        issue_request_sense(hpusbscsi);
 505                } else {
 506                        /* we request sense after an eventual data transfer */
 507                        hpusbscsi->state = HP_STATE_ERROR;
 508                }
 509        }
 510
 511        if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT && scsi_state != CHECK_CONDITION <<1)
 512                /* we do a callback to the scsi layer if and only if all data has been transfered */
 513                hpusbscsi->scallback(hpusbscsi->srb);
 514
 515        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 516        switch (hpusbscsi->state) {
 517        case HP_STATE_WAIT:
 518                hpusbscsi->state = HP_STATE_FREE;
 519        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 520                break;
 521        case HP_STATE_WORKING:
 522        case HP_STATE_BEGINNING:
 523                hpusbscsi->state = HP_STATE_PREMATURE;
 524        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 525                break;
 526        case HP_STATE_ERROR:
 527                break;
 528        default:
 529                printk(KERN_ERR"hpusbscsi: Unexpected status report.\n");
 530        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 531                hpusbscsi->state = HP_STATE_FREE;
 532        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 533                break;
 534        }
 535}
 536
 537static void simple_command_callback(struct urb *u)
 538{
 539        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 540        if (u->status<0) {
 541                handle_usb_error(hpusbscsi);
 542                return;
 543        }
 544        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 545        if (hpusbscsi->state != HP_STATE_PREMATURE) {
 546                PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 547                hpusbscsi->state = HP_STATE_WAIT;
 548        } else {
 549                if (hpusbscsi->scallback != NULL)
 550                        hpusbscsi->scallback(hpusbscsi->srb);
 551                hpusbscsi->state = HP_STATE_FREE;
 552        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 553        }
 554}
 555
 556static void scatter_gather_callback(struct urb *u)
 557{
 558        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 559        struct scatterlist *sg = hpusbscsi->srb->buffer;
 560        usb_urb_callback callback;
 561        int res;
 562
 563        PDEBUG(1, "Going through scatter/gather"); // bonzo - this gets hit a lot - maybe make it a 2
 564        if (u->status < 0) {
 565                handle_usb_error(hpusbscsi);
 566                return;
 567        }
 568
 569        if (hpusbscsi->fragment + 1 != hpusbscsi->srb->use_sg)
 570                callback = scatter_gather_callback;
 571        else
 572                callback = simple_done;
 573
 574        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 575        if (hpusbscsi->state != HP_STATE_PREMATURE)
 576                hpusbscsi->state = HP_STATE_WORKING;
 577        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 578
 579        FILL_BULK_URB(
 580                u,
 581                hpusbscsi->dev,
 582                hpusbscsi->current_data_pipe,
 583                sg[hpusbscsi->fragment].address,
 584                sg[hpusbscsi->fragment++].length,
 585                callback,
 586                hpusbscsi
 587        );
 588
 589        res = usb_submit_urb(u);
 590        if (res)
 591                handle_usb_error(hpusbscsi);
 592        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 593}
 594
 595static void simple_done (struct urb *u)
 596{
 597        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 598
 599        if (u->status < 0) {
 600                handle_usb_error(hpusbscsi);
 601                return;
 602        }
 603        PDEBUG(1, "Data transfer done");
 604        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 605        if (hpusbscsi->state != HP_STATE_PREMATURE) {
 606                if (u->status < 0) {
 607                        handle_usb_error(hpusbscsi);
 608                } else {
 609                        if (hpusbscsi->state != HP_STATE_ERROR) {
 610                                hpusbscsi->state = HP_STATE_WAIT;
 611                        } else {
 612                                issue_request_sense(hpusbscsi);
 613                        }
 614                PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 615                }
 616        } else {
 617                if (hpusbscsi->scallback != NULL)
 618                        hpusbscsi->scallback(hpusbscsi->srb);
 619                hpusbscsi->state = HP_STATE_FREE;
 620        }
 621}
 622
 623static void simple_payload_callback (struct urb *u)
 624{
 625        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 626        int res;
 627
 628        if (u->status<0) {
 629                handle_usb_error(hpusbscsi);
 630                return;
 631        }
 632
 633        FILL_BULK_URB(
 634                u,
 635                hpusbscsi->dev,
 636                hpusbscsi->current_data_pipe,
 637                hpusbscsi->srb->buffer,
 638                hpusbscsi->srb->bufflen,
 639                simple_done,
 640                hpusbscsi
 641        );
 642
 643        res = usb_submit_urb(u);
 644        if (res) {
 645                handle_usb_error(hpusbscsi);
 646                return;
 647        }
 648        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 649        if (hpusbscsi->state != HP_STATE_PREMATURE) {
 650                hpusbscsi->state = HP_STATE_WORKING;
 651        PDEBUG(2, "state= %s", states[hpusbscsi->state]);
 652        }
 653}
 654
 655static void request_sense_callback (struct urb *u)
 656{
 657        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 658
 659        if (u->status<0) {
 660                handle_usb_error(hpusbscsi);
 661                return;
 662        }
 663
 664        FILL_BULK_URB(
 665                u,
 666                hpusbscsi->dev,
 667                hpusbscsi->current_data_pipe,
 668                hpusbscsi->srb->sense_buffer,
 669                SCSI_SENSE_BUFFERSIZE,
 670                simple_done,
 671                hpusbscsi
 672        );
 673
 674        if (0 > usb_submit_urb(u)) {
 675                handle_usb_error(hpusbscsi);
 676                return;
 677        }
 678        if (hpusbscsi->state != HP_STATE_PREMATURE && hpusbscsi->state != HP_STATE_ERROR)
 679                hpusbscsi->state = HP_STATE_WORKING;
 680}
 681
 682static void issue_request_sense (struct hpusbscsi *hpusbscsi)
 683{
 684        FILL_BULK_URB(
 685                &hpusbscsi->dataurb,
 686                hpusbscsi->dev,
 687                usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out),
 688                &hpusbscsi->sense_command,
 689                SENSE_COMMAND_SIZE,
 690                request_sense_callback,
 691                hpusbscsi
 692        );
 693
 694        hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
 695
 696        if (0 > usb_submit_urb(&hpusbscsi->dataurb)) {
 697                handle_usb_error(hpusbscsi);
 698        }
 699}
 700
 701
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.