driver-core: fix devtmpfs crash on s390
[safe/jmp/linux-2.6] / drivers / scsi / scsi_lib.c
index d7c6c75..d892768 100644 (file)
@@ -859,6 +859,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                                case 0x07: /* operation in progress */
                                case 0x08: /* Long write in progress */
                                case 0x09: /* self test in progress */
+                               case 0x14: /* space allocation in progress */
                                        action = ACTION_DELAYED_RETRY;
                                        break;
                                default:
@@ -896,9 +897,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        scsi_print_result(cmd);
                        if (driver_byte(result) & DRIVER_SENSE)
                                scsi_print_sense("", cmd);
+                       scsi_print_command(cmd);
                }
-               blk_end_request_all(req, -EIO);
-               scsi_next_command(cmd);
+               if (blk_end_request_err(req, error))
+                       scsi_requeue_command(q, cmd);
+               else
+                       scsi_next_command(cmd);
                break;
        case ACTION_REPREP:
                /* Unprep the request and put it back at the head of the queue.
@@ -1207,6 +1211,7 @@ int scsi_prep_fn(struct request_queue *q, struct request *req)
                ret = scsi_setup_blk_pc_cmnd(sdev, req);
        return scsi_prep_return(q, req, ret);
 }
+EXPORT_SYMBOL(scsi_prep_fn);
 
 /*
  * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else
@@ -1262,10 +1267,8 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
                if (--starget->target_blocked == 0) {
                        SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget,
                                         "unblocking target at zero depth\n"));
-               } else {
-                       blk_plug_device(sdev->request_queue);
+               } else
                        return 0;
-               }
        }
 
        if (scsi_target_is_busy(starget)) {
@@ -1357,9 +1360,9 @@ static int scsi_lld_busy(struct request_queue *q)
 static void scsi_kill_request(struct request *req, struct request_queue *q)
 {
        struct scsi_cmnd *cmd = req->special;
-       struct scsi_device *sdev = cmd->device;
-       struct scsi_target *starget = scsi_target(sdev);
-       struct Scsi_Host *shost = sdev->host;
+       struct scsi_device *sdev;
+       struct scsi_target *starget;
+       struct Scsi_Host *shost;
 
        blk_start_request(req);
 
@@ -1369,6 +1372,9 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
                BUG();
        }
 
+       sdev = cmd->device;
+       starget = scsi_target(sdev);
+       shost = sdev->host;
        scsi_init_cmd_errh(cmd);
        cmd->result = DID_NO_CONNECT << 16;
        atomic_inc(&cmd->device->iorequest_cnt);
@@ -2414,20 +2420,18 @@ int
 scsi_internal_device_unblock(struct scsi_device *sdev)
 {
        struct request_queue *q = sdev->request_queue; 
-       int err;
        unsigned long flags;
        
        /* 
         * Try to transition the scsi device to SDEV_RUNNING
         * and goose the device queue if successful.  
         */
-       err = scsi_device_set_state(sdev, SDEV_RUNNING);
-       if (err) {
-               err = scsi_device_set_state(sdev, SDEV_CREATED);
-
-               if (err)
-                       return err;
-       }
+       if (sdev->sdev_state == SDEV_BLOCK)
+               sdev->sdev_state = SDEV_RUNNING;
+       else if (sdev->sdev_state == SDEV_CREATED_BLOCK)
+               sdev->sdev_state = SDEV_CREATED;
+       else
+               return -EINVAL;
 
        spin_lock_irqsave(q->queue_lock, flags);
        blk_start_queue(q);