]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge by hand (conflicts in sd.c)
authorJames Bottomley <jejb@titanic.(none)>
Tue, 6 Sep 2005 22:52:54 +0000 (17:52 -0500)
committerJames Bottomley <jejb@titanic.(none)>
Tue, 6 Sep 2005 22:52:54 +0000 (17:52 -0500)
1  2 
drivers/scsi/Kconfig
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_ioctl.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/st.c
include/scsi/scsi_eh.h

diff --combined drivers/scsi/Kconfig
index 12c208fb18c516de702cb575cf82c8348480b53c,68adc3cc8ad207c2630ca4b2a6d6d8f8e1b1a94e..b3ae796eb62485faa023ded387b67a8efc4d57b9
@@@ -1,5 -1,11 +1,11 @@@
  menu "SCSI device support"
  
+ config RAID_ATTRS
+       tristate "RAID Transport Class"
+       default n
+       ---help---
+         Provides RAID
  config SCSI
        tristate "SCSI device support"
        ---help---
@@@ -424,7 -430,7 +430,7 @@@ config SCSI_IN200
  source "drivers/scsi/megaraid/Kconfig.megaraid"
  
  config SCSI_SATA
 -      bool "Serial ATA (SATA) support"
 +      tristate "Serial ATA (SATA) support"
        depends on SCSI
        help
          This driver family supports Serial ATA host controllers
@@@ -1696,7 -1702,7 +1702,7 @@@ config TT_DMA_EMU
  
  config MAC_SCSI
        bool "Macintosh NCR5380 SCSI"
 -      depends on MAC && SCSI
 +      depends on MAC && SCSI=y
        help
          This is the NCR 5380 SCSI controller included on most of the 68030
          based Macintoshes.  If you have one of these say Y and read the
@@@ -1717,7 -1723,7 +1723,7 @@@ config SCSI_MAC_ES
  
  config MVME147_SCSI
        bool "WD33C93 SCSI driver for MVME147"
 -      depends on MVME147 && SCSI
 +      depends on MVME147 && SCSI=y
        help
          Support for the on-board SCSI controller on the Motorola MVME147
          single-board computer.
@@@ -1758,7 -1764,7 +1764,7 @@@ config SUN3_SCS
  
  config SUN3X_ESP
        bool "Sun3x ESP SCSI"
 -      depends on SUN3X && SCSI
 +      depends on SUN3X && SCSI=y
        help
          The ESP was an on-board SCSI controller used on Sun 3/80
          machines.  Say Y here to compile in support for it.
index 54173887e1605af55efa56fe7da334e85291bb89,4096d523d08d2e8f0dfe0e512f86056345a793a6..c932b3b94490833a1f306a4c418985aa5749431a
  
  static struct scsi_transport_template *ahc_linux_transport_template = NULL;
  
- /*
-  * Include aiclib.c as part of our
-  * "module dependencies are hard" work around.
-  */
- #include "aiclib.c"
  #include <linux/init.h>               /* __setup */
  #include <linux/mm.h>         /* For fetching system memory size */
  #include <linux/blkdev.h>             /* For block_size() */
@@@ -391,7 -385,6 +385,6 @@@ static int ahc_linux_run_command(struc
                                 struct ahc_linux_device *,
                                 struct scsi_cmnd *);
  static void ahc_linux_setup_tag_info_global(char *p);
- static aic_option_callback_t ahc_linux_setup_tag_info;
  static int  aic7xxx_setup(char *s);
  
  static int ahc_linux_unit;
@@@ -920,6 -913,86 +913,86 @@@ ahc_linux_setup_tag_info(u_long arg, in
        }
  }
  
+ static char *
+ ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
+                      void (*callback)(u_long, int, int, int32_t),
+                      u_long callback_arg)
+ {
+       char    *tok_end;
+       char    *tok_end2;
+       int      i;
+       int      instance;
+       int      targ;
+       int      done;
+       char     tok_list[] = {'.', ',', '{', '}', '\0'};
+       /* All options use a ':' name/arg separator */
+       if (*opt_arg != ':')
+               return (opt_arg);
+       opt_arg++;
+       instance = -1;
+       targ = -1;
+       done = FALSE;
+       /*
+        * Restore separator that may be in
+        * the middle of our option argument.
+        */
+       tok_end = strchr(opt_arg, '\0');
+       if (tok_end < end)
+               *tok_end = ',';
+       while (!done) {
+               switch (*opt_arg) {
+               case '{':
+                       if (instance == -1) {
+                               instance = 0;
+                       } else {
+                               if (depth > 1) {
+                                       if (targ == -1)
+                                               targ = 0;
+                               } else {
+                                       printf("Malformed Option %s\n",
+                                              opt_name);
+                                       done = TRUE;
+                               }
+                       }
+                       opt_arg++;
+                       break;
+               case '}':
+                       if (targ != -1)
+                               targ = -1;
+                       else if (instance != -1)
+                               instance = -1;
+                       opt_arg++;
+                       break;
+               case ',':
+               case '.':
+                       if (instance == -1)
+                               done = TRUE;
+                       else if (targ >= 0)
+                               targ++;
+                       else if (instance >= 0)
+                               instance++;
+                       opt_arg++;
+                       break;
+               case '\0':
+                       done = TRUE;
+                       break;
+               default:
+                       tok_end = end;
+                       for (i = 0; tok_list[i]; i++) {
+                               tok_end2 = strchr(opt_arg, tok_list[i]);
+                               if ((tok_end2) && (tok_end2 < tok_end))
+                                       tok_end = tok_end2;
+                       }
+                       callback(callback_arg, instance, targ,
+                                simple_strtol(opt_arg, NULL, 0));
+                       opt_arg = tok_end;
+                       break;
+               }
+       }
+       return (opt_arg);
+ }
  /*
   * Handle Linux boot parameters. This routine allows for assigning a value
   * to a parameter with a ':' between the parameter and the value.
@@@ -974,7 -1047,7 +1047,7 @@@ aic7xxx_setup(char *s
                if (strncmp(p, "global_tag_depth", n) == 0) {
                        ahc_linux_setup_tag_info_global(p + n);
                } else if (strncmp(p, "tag_info", n) == 0) {
-                       s = aic_parse_brace_option("tag_info", p + n, end,
+                       s = ahc_parse_brace_option("tag_info", p + n, end,
                            2, ahc_linux_setup_tag_info, 0);
                } else if (p[n] == ':') {
                        *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
@@@ -1266,12 -1339,14 +1339,12 @@@ ahc_platform_set_tags(struct ahc_softc 
        }
        switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
        case AHC_DEV_Q_BASIC:
 -              scsi_adjust_queue_depth(sdev,
 -                                      MSG_SIMPLE_TASK,
 -                                      dev->openings + dev->active);
 +              scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
 +              scsi_activate_tcq(sdev, dev->openings + dev->active);
                break;
        case AHC_DEV_Q_TAGGED:
 -              scsi_adjust_queue_depth(sdev,
 -                                      MSG_ORDERED_TASK,
 -                                      dev->openings + dev->active);
 +              scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
 +              scsi_activate_tcq(sdev, dev->openings + dev->active);
                break;
        default:
                /*
                 * serially on the controller/device.  This should
                 * remove some latency.
                 */
 -              scsi_adjust_queue_depth(sdev,
 -                                      /*NON-TAGGED*/0,
 -                                      /*queue depth*/2);
 +              scsi_deactivate_tcq(sdev, 2);
                break;
        }
  }
@@@ -1633,9 -1710,9 +1706,9 @@@ ahc_send_async(struct ahc_softc *ahc, c
                spi_period(starget) = tinfo->curr.period;
                spi_width(starget) = tinfo->curr.width;
                spi_offset(starget) = tinfo->curr.offset;
 -              spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
 -              spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
 -              spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
 +              spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
 +              spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
 +              spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
                spi_display_xfer_agreement(starget);
                break;
        }
@@@ -2425,14 -2502,12 +2498,14 @@@ static void ahc_linux_set_dt(struct scs
        unsigned int ppr_options = tinfo->goal.ppr_options
                & ~MSG_EXT_PPR_DT_REQ;
        unsigned int period = tinfo->goal.period;
 +      unsigned int width = tinfo->goal.width;
        unsigned long flags;
        struct ahc_syncrate *syncrate;
  
        if (dt) {
 -              period = 9;     /* 12.5ns is the only period valid for DT */
                ppr_options |= MSG_EXT_PPR_DT_REQ;
 +              if (!width)
 +                      ahc_linux_set_width(starget, 1);
        } else if (period == 9)
                period = 10;    /* if resetting DT, period must be >= 25ns */
  
index 2686d5672e5e5525bcd9f2fccdc391d2036e7224,ae28bcb79242d9d961fa4b520c15e7a6d4050c45..895c9452be4ca65cc3aebf78ee8bd9f319618c15
@@@ -20,6 -20,7 +20,7 @@@
  #include <linux/string.h>
  #include <linux/slab.h>
  #include <linux/kernel.h>
+ #include <linux/kthread.h>
  #include <linux/interrupt.h>
  #include <linux/blkdev.h>
  #include <linux/delay.h>
@@@ -115,7 -116,6 +116,6 @@@ void scsi_add_timer(struct scsi_cmnd *s
  
        add_timer(&scmd->eh_timeout);
  }
- EXPORT_SYMBOL(scsi_add_timer);
  
  /**
   * scsi_delete_timer - Delete/cancel timer for a given function.
@@@ -143,7 -143,6 +143,6 @@@ int scsi_delete_timer(struct scsi_cmnd 
  
        return rtn;
  }
- EXPORT_SYMBOL(scsi_delete_timer);
  
  /**
   * scsi_times_out - Timeout function for normal scsi commands.
@@@ -776,9 -775,11 +775,11 @@@ retry_tur
                __FUNCTION__, scmd, rtn));
        if (rtn == SUCCESS)
                return 0;
-       else if (rtn == NEEDS_RETRY)
+       else if (rtn == NEEDS_RETRY) {
                if (retry_cnt--)
                        goto retry_tur;
+               return 0;
+       }
        return 1;
  }
  
@@@ -1583,16 -1584,8 +1584,8 @@@ int scsi_error_handler(void *data
        int rtn;
        DECLARE_MUTEX_LOCKED(sem);
  
-       /*
-        *    Flush resources
-        */
-       daemonize("scsi_eh_%d", shost->host_no);
        current->flags |= PF_NOFREEZE;
        shost->eh_wait = &sem;
-       shost->ehandler = current;
  
        /*
         * Wake up the thread that created us.
        SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
                                          " scsi_eh_%d\n",shost->host_no));
  
-       complete(shost->eh_notify);
        while (1) {
                /*
                 * If we get a signal, it means we are supposed to go
                 * semaphores isn't unreasonable.
                 */
                down_interruptible(&sem);
-               if (shost->eh_kill)
+               if (kthread_should_stop())
                        break;
  
                SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
         * Make sure that nobody tries to wake us up again.
         */
        shost->eh_wait = NULL;
-       /*
-        * Knock this down too.  From this point on, the host is flying
-        * without a pilot.  If this is because the module is being unloaded,
-        * that's fine.  If the user sent a signal to this thing, we are
-        * potentially in real danger.
-        */
-       shost->eh_active = 0;
-       shost->ehandler = NULL;
-       /*
-        * If anyone is waiting for us to exit (i.e. someone trying to unload
-        * a driver), then wake up that process to let them know we are on
-        * the way out the door.
-        */
-       complete_and_exit(shost->eh_notify, 0);
        return 0;
  }
  
@@@ -1847,16 -1822,12 +1822,16 @@@ EXPORT_SYMBOL(scsi_reset_provider)
  int scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
                           struct scsi_sense_hdr *sshdr)
  {
 -      if (!sense_buffer || !sb_len || (sense_buffer[0] & 0x70) != 0x70)
 +      if (!sense_buffer || !sb_len)
                return 0;
  
        memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
  
        sshdr->response_code = (sense_buffer[0] & 0x7f);
 +
 +      if (!scsi_sense_valid(sshdr))
 +              return 0;
 +
        if (sshdr->response_code >= 0x72) {
                /*
                 * descriptor format
index 179a767d221d5be2fc78478c292e528648fb0a9e,946c31fa64660aa150e33e650f0d005b5b0bbf4f..b7fddac813474c0903d37d88e6f6f7ec03b092f5
  
  #define MAX_BUF PAGE_SIZE
  
- /*
-  * If we are told to probe a host, we will return 0 if  the host is not
-  * present, 1 if the host is present, and will return an identifying
-  * string at *arg, if arg is non null, filling to the length stored at
-  * (int *) arg
+ /**
+  * ioctl_probe  --  return host identification
+  * @host:     host to identify
+  * @buffer:   userspace buffer for identification
+  *
+  * Return an identifying string at @buffer, if @buffer is non-NULL, filling
+  * to the length stored at * (int *) @buffer.
   */
  static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
  {
        unsigned int len, slen;
        const char *string;
-       int temp = host->hostt->present;
  
-       if (temp && buffer) {
+       if (buffer) {
                if (get_user(len, (unsigned int __user *) buffer))
                        return -EFAULT;
  
@@@ -59,7 -59,7 +59,7 @@@
                                return -EFAULT;
                }
        }
-       return temp;
+       return 1;
  }
  
  /*
  static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
                                  int timeout, int retries)
  {
 -      struct scsi_request *sreq;
        int result;
        struct scsi_sense_hdr sshdr;
  
        SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
  
 -      sreq = scsi_allocate_request(sdev, GFP_KERNEL);
 -      if (!sreq) {
 -              printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
 -              return -ENOMEM;
 -      }
 -
 -      sreq->sr_data_direction = DMA_NONE;
 -        scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
 +      result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
 +                                &sshdr, timeout, retries);
  
 -      SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));
 +      SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", result));
  
 -      if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
 -          (scsi_request_normalize_sense(sreq, &sshdr))) {
 +      if ((driver_byte(result) & DRIVER_SENSE) &&
 +          (scsi_sense_valid(&sshdr))) {
                switch (sshdr.sense_key) {
                case ILLEGAL_REQUEST:
                        if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
                case UNIT_ATTENTION:
                        if (sdev->removable) {
                                sdev->changed = 1;
 -                              sreq->sr_result = 0;    /* This is no longer considered an error */
 +                              result = 0;     /* This is no longer considered an error */
                                break;
                        }
                default:        /* Fall through for non-removable media */
                               sdev->channel,
                               sdev->id,
                               sdev->lun,
 -                             sreq->sr_result);
 -                      scsi_print_req_sense("   ", sreq);
 +                             result);
 +                      scsi_print_sense_hdr("   ", &sshdr);
                        break;
                }
        }
  
 -      result = sreq->sr_result;
        SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
 -      scsi_release_request(sreq);
        return result;
  }
  
@@@ -199,8 -208,8 +199,8 @@@ int scsi_ioctl_send_command(struct scsi
  {
        char *buf;
        unsigned char cmd[MAX_COMMAND_SIZE];
 +      unsigned char sense[SCSI_SENSE_BUFFERSIZE];
        char __user *cmd_in;
 -      struct scsi_request *sreq;
        unsigned char opcode;
        unsigned int inlen, outlen, cmdlen;
        unsigned int needed, buf_needed;
                break;
        }
  
 -      sreq = scsi_allocate_request(sdev, GFP_KERNEL);
 -        if (!sreq) {
 -                result = -EINTR;
 -                goto error;
 -        }
 -
 -      sreq->sr_data_direction = data_direction;
 -        scsi_wait_req(sreq, cmd, buf, needed, timeout, retries);
 +      result = scsi_execute(sdev, cmd, data_direction, buf, needed,
 +                            sense, timeout, retries, 0);
  
        /* 
         * If there was an error condition, pass the info back to the user. 
         */
 -      result = sreq->sr_result;
        if (result) {
 -              int sb_len = sizeof(sreq->sr_sense_buffer);
 +              int sb_len = sizeof(*sense);
  
                sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;
 -              if (copy_to_user(cmd_in, sreq->sr_sense_buffer, sb_len))
 +              if (copy_to_user(cmd_in, sense, sb_len))
                        result = -EFAULT;
        } else {
                if (copy_to_user(cmd_in, buf, outlen))
                        result = -EFAULT;
        }       
  
 -      scsi_release_request(sreq);
  error:
        kfree(buf);
        return result;
diff --combined drivers/scsi/sd.c
index 611ccde84778e03387cee06612c91d6911e1e782,41ba0809f7918aa859baa89f2fd152132a62e1b6..de564b386052a1c1c0015f76088c2f9db6fc529c
@@@ -59,6 -59,7 +59,6 @@@
  #include <scsi/scsi_eh.h>
  #include <scsi/scsi_host.h>
  #include <scsi/scsi_ioctl.h>
 -#include <scsi/scsi_request.h>
  #include <scsi/scsicam.h>
  
  #include "scsi_logging.h"
@@@ -124,7 -125,7 +124,7 @@@ static int sd_issue_flush(struct devic
  static void sd_end_flush(request_queue_t *, struct request *);
  static int sd_prepare_flush(request_queue_t *, struct request *);
  static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 -               struct scsi_request *SRpnt, unsigned char *buffer);
 +                           unsigned char *buffer);
  
  static struct scsi_driver sd_template = {
        .owner                  = THIS_MODULE,
@@@ -681,13 -682,19 +681,13 @@@ not_present
  
  static int sd_sync_cache(struct scsi_device *sdp)
  {
 -      struct scsi_request *sreq;
        int retries, res;
 +      struct scsi_sense_hdr sshdr;
  
        if (!scsi_device_online(sdp))
                return -ENODEV;
  
 -      sreq = scsi_allocate_request(sdp, GFP_KERNEL);
 -      if (!sreq) {
 -              printk("FAILED\n  No memory for request\n");
 -              return -ENOMEM;
 -      }
  
 -      sreq->sr_data_direction = DMA_NONE;
        for (retries = 3; retries > 0; --retries) {
                unsigned char cmd[10] = { 0 };
  
                 * Leave the rest of the command zero to indicate
                 * flush everything.
                 */
 -              scsi_wait_req(sreq, cmd, NULL, 0, SD_TIMEOUT, SD_MAX_RETRIES);
 -              if (sreq->sr_result == 0)
 +              res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
 +                                     SD_TIMEOUT, SD_MAX_RETRIES);
 +              if (res == 0)
                        break;
        }
  
 -      res = sreq->sr_result;
 -      if (res) {
 -              printk(KERN_WARNING "FAILED\n  status = %x, message = %02x, "
 +      if (res) {              printk(KERN_WARNING "FAILED\n  status = %x, message = %02x, "
                                    "host = %d, driver = %02x\n  ",
                                    status_byte(res), msg_byte(res),
                                    host_byte(res), driver_byte(res));
                        if (driver_byte(res) & DRIVER_SENSE)
 -                              scsi_print_req_sense("sd", sreq);
 +                              scsi_print_sense_hdr("sd", &sshdr);
        }
  
 -      scsi_release_request(sreq);
        return res;
  }
  
@@@ -948,19 -957,22 +948,19 @@@ static void sd_rw_intr(struct scsi_cmn
        scsi_io_completion(SCpnt, good_bytes, block_sectors << 9);
  }
  
 -static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp)
 +static int media_not_present(struct scsi_disk *sdkp,
 +                           struct scsi_sense_hdr *sshdr)
  {
 -      struct scsi_sense_hdr sshdr;
  
 -      if (!srp->sr_result)
 -              return 0;
 -      if (!(driver_byte(srp->sr_result) & DRIVER_SENSE))
 +      if (!scsi_sense_valid(sshdr))
                return 0;
        /* not invoked for commands that could return deferred errors */
 -      if (scsi_request_normalize_sense(srp, &sshdr)) {
 -              if (sshdr.sense_key != NOT_READY &&
 -                  sshdr.sense_key != UNIT_ATTENTION)
 -                      return 0;
 -              if (sshdr.asc != 0x3A) /* medium not present */
 -                      return 0;
 -      }
 +      if (sshdr->sense_key != NOT_READY &&
 +          sshdr->sense_key != UNIT_ATTENTION)
 +              return 0;
 +      if (sshdr->asc != 0x3A) /* medium not present */
 +              return 0;
 +
        set_media_not_present(sdkp);
        return 1;
  }
   * spinup disk - called only in sd_revalidate_disk()
   */
  static void
 -sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
 -             struct scsi_request *SRpnt, unsigned char *buffer) {
 +sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 +{
        unsigned char cmd[10];
-       unsigned long spintime_value = 0;
+       unsigned long spintime_expire = 0;
        int retries, spintime;
        unsigned int the_result;
        struct scsi_sense_hdr sshdr;
                        cmd[0] = TEST_UNIT_READY;
                        memset((void *) &cmd[1], 0, 9);
  
 -                      SRpnt->sr_cmd_len = 0;
 -                      memset(SRpnt->sr_sense_buffer, 0,
 -                             SCSI_SENSE_BUFFERSIZE);
 -                      SRpnt->sr_data_direction = DMA_NONE;
 +                      the_result = scsi_execute_req(sdkp->device, cmd,
 +                                                    DMA_NONE, NULL, 0,
 +                                                    &sshdr, SD_TIMEOUT,
 +                                                    SD_MAX_RETRIES);
  
 -                      scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
 -                                     0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES);
 -
 -                      the_result = SRpnt->sr_result;
                        if (the_result)
 -                              sense_valid = scsi_request_normalize_sense(
 -                                                      SRpnt, &sshdr);
 +                              sense_valid = scsi_sense_valid(&sshdr);
                        retries++;
                } while (retries < 3 && 
                         (!scsi_status_is_good(the_result) ||
                 * any media in it, don't bother with any of the rest of
                 * this crap.
                 */
 -              if (media_not_present(sdkp, SRpnt))
 +              if (media_not_present(sdkp, &sshdr))
                        return;
  
                if ((driver_byte(the_result) & DRIVER_SENSE) == 0) {
                                cmd[1] = 1;     /* Return immediately */
                                memset((void *) &cmd[2], 0, 8);
                                cmd[4] = 1;     /* Start spin cycle */
 -                              SRpnt->sr_cmd_len = 0;
 -                              memset(SRpnt->sr_sense_buffer, 0,
 -                                      SCSI_SENSE_BUFFERSIZE);
 -
 -                              SRpnt->sr_data_direction = DMA_NONE;
 -                              scsi_wait_req(SRpnt, (void *)cmd, 
 -                                            (void *) buffer, 0/*512*/, 
 -                                            SD_TIMEOUT, SD_MAX_RETRIES);
 +                              scsi_execute_req(sdkp->device, cmd, DMA_NONE,
 +                                               NULL, 0, &sshdr,
 +                                               SD_TIMEOUT, SD_MAX_RETRIES);
-                               spintime_value = jiffies;
+                               spintime_expire = jiffies + 100 * HZ;
+                               spintime = 1;
                        }
-                       spintime = 1;
                        /* Wait 1 second for next try */
                        msleep(1000);
                        printk(".");
+               /*
+                * Wait for USB flash devices with slow firmware.
+                * Yes, this sense key/ASC combination shouldn't
+                * occur here.  It's characteristic of these devices.
+                */
+               } else if (sense_valid &&
+                               sshdr.sense_key == UNIT_ATTENTION &&
+                               sshdr.asc == 0x28) {
+                       if (!spintime) {
+                               spintime_expire = jiffies + 5 * HZ;
+                               spintime = 1;
+                       }
+                       /* Wait 1 second for next try */
+                       msleep(1000);
                } else {
                        /* we don't understand the sense code, so it's
                         * probably pointless to loop */
                        if(!spintime) {
                                printk(KERN_NOTICE "%s: Unit Not Ready, "
                                        "sense:\n", diskname);
 -                              scsi_print_req_sense("", SRpnt);
 +                              scsi_print_sense_hdr("", &sshdr);
                        }
                        break;
                }
                                
-       } while (spintime &&
-                time_after(spintime_value + 100 * HZ, jiffies));
+       } while (spintime && time_before_eq(jiffies, spintime_expire));
  
        if (spintime) {
                if (scsi_status_is_good(the_result))
   */
  static void
  sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 -               struct scsi_request *SRpnt, unsigned char *buffer) {
 +               unsigned char *buffer)
 +{
        unsigned char cmd[16];
 -      struct scsi_device *sdp = sdkp->device;
        int the_result, retries;
        int sector_size = 0;
        int longrc = 0;
        struct scsi_sense_hdr sshdr;
        int sense_valid = 0;
 +      struct scsi_device *sdp = sdkp->device;
  
  repeat:
        retries = 3;
                        memset((void *) buffer, 0, 8);
                }
                
 -              SRpnt->sr_cmd_len = 0;
 -              memset(SRpnt->sr_sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 -              SRpnt->sr_data_direction = DMA_FROM_DEVICE;
 -
 -              scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
 -                            longrc ? 12 : 8, SD_TIMEOUT, SD_MAX_RETRIES);
 +              the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
 +                                            buffer, longrc ? 12 : 8, &sshdr,
 +                                            SD_TIMEOUT, SD_MAX_RETRIES);
  
 -              if (media_not_present(sdkp, SRpnt))
 +              if (media_not_present(sdkp, &sshdr))
                        return;
  
 -              the_result = SRpnt->sr_result;
                if (the_result)
 -                      sense_valid = scsi_request_normalize_sense(SRpnt,
 -                                                                 &sshdr);
 +                      sense_valid = scsi_sense_valid(&sshdr);
                retries--;
  
        } while (the_result && retries);
                       driver_byte(the_result));
  
                if (driver_byte(the_result) & DRIVER_SENSE)
 -                      scsi_print_req_sense("sd", SRpnt);
 +                      scsi_print_sense_hdr("sd", &sshdr);
                else
                        printk("%s : sense not available. \n", diskname);
  
@@@ -1270,13 -1310,11 +1284,13 @@@ got_data
  
  /* called with buffer of length 512 */
  static inline int
 -sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
 -               unsigned char *buffer, int len, struct scsi_mode_data *data)
 +sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage,
 +               unsigned char *buffer, int len, struct scsi_mode_data *data,
 +               struct scsi_sense_hdr *sshdr)
  {
 -      return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len,
 -                               SD_TIMEOUT, SD_MAX_RETRIES, data);
 +      return scsi_mode_sense(sdp, dbd, modepage, buffer, len,
 +                             SD_TIMEOUT, SD_MAX_RETRIES, data,
 +                             sshdr);
  }
  
  /*
   */
  static void
  sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
 -                 struct scsi_request *SRpnt, unsigned char *buffer) {
 +                         unsigned char *buffer)
 +{
        int res;
 +      struct scsi_device *sdp = sdkp->device;
        struct scsi_mode_data data;
  
        set_disk_ro(sdkp->disk, 0);
 -      if (sdkp->device->skip_ms_page_3f) {
 +      if (sdp->skip_ms_page_3f) {
                printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname);
                return;
        }
  
 -      if (sdkp->device->use_192_bytes_for_3f) {
 -              res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 192, &data);
 +      if (sdp->use_192_bytes_for_3f) {
 +              res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 192, &data, NULL);
        } else {
                /*
                 * First attempt: ask for all pages (0x3F), but only 4 bytes.
                 * We have to start carefully: some devices hang if we ask
                 * for more than is available.
                 */
 -              res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4, &data);
 +              res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 4, &data, NULL);
  
                /*
                 * Second attempt: ask for page 0 When only page 0 is
                 * CDB.
                 */
                if (!scsi_status_is_good(res))
 -                      res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4, &data);
 +                      res = sd_do_mode_sense(sdp, 0, 0, buffer, 4, &data, NULL);
  
                /*
                 * Third attempt: ask 255 bytes, as we did earlier.
                 */
                if (!scsi_status_is_good(res))
 -                      res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255,
 -                                             &data);
 +                      res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 255,
 +                                             &data, NULL);
        }
  
        if (!scsi_status_is_good(res)) {
   */
  static void
  sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 -                 struct scsi_request *SRpnt, unsigned char *buffer)
 +                 unsigned char *buffer)
  {
        int len = 0, res;
 +      struct scsi_device *sdp = sdkp->device;
  
        int dbd;
        int modepage;
        struct scsi_mode_data data;
        struct scsi_sense_hdr sshdr;
  
 -      if (sdkp->device->skip_ms_page_8)
 +      if (sdp->skip_ms_page_8)
                goto defaults;
  
 -      if (sdkp->device->type == TYPE_RBC) {
 +      if (sdp->type == TYPE_RBC) {
                modepage = 6;
                dbd = 8;
        } else {
        }
  
        /* cautiously ask */
 -      res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
 +      res = sd_do_mode_sense(sdp, dbd, modepage, buffer, 4, &data, &sshdr);
  
        if (!scsi_status_is_good(res))
                goto bad_sense;
        len += data.header_length + data.block_descriptor_length;
  
        /* Get the data */
 -      res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len, &data);
 +      res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
  
        if (scsi_status_is_good(res)) {
                const char *types[] = {
        }
  
  bad_sense:
 -      if (scsi_request_normalize_sense(SRpnt, &sshdr) &&
 +      if (scsi_sense_valid(&sshdr) &&
            sshdr.sense_key == ILLEGAL_REQUEST &&
            sshdr.asc == 0x24 && sshdr.ascq == 0x0)
                printk(KERN_NOTICE "%s: cache data unavailable\n",
@@@ -1443,6 -1478,7 +1457,6 @@@ static int sd_revalidate_disk(struct ge
  {
        struct scsi_disk *sdkp = scsi_disk(disk);
        struct scsi_device *sdp = sdkp->device;
 -      struct scsi_request *sreq;
        unsigned char *buffer;
  
        SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
        if (!scsi_device_online(sdp))
                goto out;
  
 -      sreq = scsi_allocate_request(sdp, GFP_KERNEL);
 -      if (!sreq) {
 -              printk(KERN_WARNING "(sd_revalidate_disk:) Request allocation "
 -                     "failure.\n");
 -              goto out;
 -      }
 -
        buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA);
        if (!buffer) {
                printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation "
                       "failure.\n");
 -              goto out_release_request;
 +              goto out;
        }
  
        /* defaults, until the device tells us otherwise */
        sdkp->WCE = 0;
        sdkp->RCD = 0;
  
 -      sd_spinup_disk(sdkp, disk->disk_name, sreq, buffer);
 +      sd_spinup_disk(sdkp, disk->disk_name);
  
        /*
         * Without media there is no reason to ask; moreover, some devices
         * react badly if we do.
         */
        if (sdkp->media_present) {
 -              sd_read_capacity(sdkp, disk->disk_name, sreq, buffer);
 +              sd_read_capacity(sdkp, disk->disk_name, buffer);
                if (sdp->removable)
                        sd_read_write_protect_flag(sdkp, disk->disk_name,
 -                                      sreq, buffer);
 -              sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer);
 +                                                 buffer);
 +              sd_read_cache_type(sdkp, disk->disk_name, buffer);
        }
                
        set_capacity(disk, sdkp->capacity);
        kfree(buffer);
  
 - out_release_request: 
 -      scsi_release_request(sreq);
   out:
        return 0;
  }
diff --combined drivers/scsi/sg.c
index 052d55c167d41d04a03dac56b3e5d75bfc064db2,616c3f3e62fc5918325d6efa4c8149f1a7028e13..b1b69d738d085a0ca211381d13a34bcbedde9ff9
@@@ -61,7 -61,7 +61,7 @@@ static int sg_version_num = 30533;    /* 
  
  #ifdef CONFIG_SCSI_PROC_FS
  #include <linux/proc_fs.h>
- static char *sg_version_date = "20050328";
+ static char *sg_version_date = "20050901";
  
  static int sg_proc_init(void);
  static void sg_proc_cleanup(void);
@@@ -1794,12 -1794,12 +1794,12 @@@ st_map_user_pages(struct scatterlist *s
                  unsigned long uaddr, size_t count, int rw,
                  unsigned long max_pfn)
  {
+       unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       unsigned long start = uaddr >> PAGE_SHIFT;
+       const int nr_pages = end - start;
        int res, i, j;
-       unsigned int nr_pages;
        struct page **pages;
  
-       nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
        /* User attempted Overflow! */
        if ((uaddr + count) < uaddr)
                return -EINVAL;
@@@ -2970,22 -2970,23 +2970,22 @@@ static void * dev_seq_start(struct seq_
  {
        struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL);
  
 +      s->private = it;
        if (! it)
                return NULL;
 +
        if (NULL == sg_dev_arr)
 -              goto err1;
 +              return NULL;
        it->index = *pos;
        it->max = sg_last_dev();
        if (it->index >= it->max)
 -              goto err1;
 +              return NULL;
        return it;
 -err1:
 -      kfree(it);
 -      return NULL;
  }
  
  static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos)
  {
 -      struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
 +      struct sg_proc_deviter * it = s->private;
  
        *pos = ++it->index;
        return (it->index < it->max) ? it : NULL;
  
  static void dev_seq_stop(struct seq_file *s, void *v)
  {
 -      kfree (v);
 +      kfree(s->private);
  }
  
  static int sg_proc_open_dev(struct inode *inode, struct file *file)
diff --combined drivers/scsi/st.c
index 9aadf2fcad6a271fb2fecfea1d2a28ed36bb3afc,5325cf0ab19732bcef02df92590244d258d2f432..a93308ae97362b3fa2d0b2a76979ffca3c5da630
@@@ -17,7 -17,7 +17,7 @@@
     Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
   */
  
- static char *verstr = "20050802";
+ static char *verstr = "20050830";
  
  #include <linux/module.h>
  
@@@ -4241,10 -4241,12 +4241,10 @@@ static int __init init_st(void
                        do_create_driverfs_files();
                        return 0;
                }
 -              if (st_sysfs_class)
 -                      class_destroy(st_sysfs_class);
                unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 -
                                         ST_MAX_TAPE_ENTRIES);
        }
 +      class_destroy(st_sysfs_class);
  
        printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
        return 1;
  
  static void __exit exit_st(void)
  {
 -      if (st_sysfs_class)
 -              class_destroy(st_sysfs_class);
 -      st_sysfs_class = NULL;
        do_remove_driverfs_files();
        scsi_unregister_driver(&st_template.gendrv);
        unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
                                 ST_MAX_TAPE_ENTRIES);
 +      class_destroy(st_sysfs_class);
        kfree(scsi_tapes);
        printk(KERN_INFO "st: Unloaded.\n");
  }
@@@ -4440,12 -4444,12 +4440,12 @@@ static int st_map_user_pages(struct sca
  static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
                              unsigned long uaddr, size_t count, int rw)
  {
+       unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       unsigned long start = uaddr >> PAGE_SHIFT;
+       const int nr_pages = end - start;
        int res, i, j;
-       unsigned int nr_pages;
        struct page **pages;
  
-       nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
        /* User attempted Overflow! */
        if ((uaddr + count) < uaddr)
                return -EINVAL;
diff --combined include/scsi/scsi_eh.h
index b24d224281bd4705678f3d9efa44cde11ff3a918,4b71095be68149cdb71357519d1995bec43e0a82..fabd879c2f2e13e44f41a08083241fc6a20a6914
@@@ -26,18 -26,7 +26,15 @@@ struct scsi_sense_hdr {             /* See SPC-3 s
        u8 additional_length;   /* always 0 for fixed sense format */
  };
  
 +static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr)
 +{
 +      if (!sshdr)
 +              return 0;
 +
 +      return (sshdr->response_code & 0x70) == 0x70;
 +}
 +
  
- extern void scsi_add_timer(struct scsi_cmnd *, int,
-               void (*)(struct scsi_cmnd *));
- extern int scsi_delete_timer(struct scsi_cmnd *);
  extern void scsi_report_bus_reset(struct Scsi_Host *, int);
  extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
  extern int scsi_block_when_processing_errors(struct scsi_device *);