scsi: hpsa: Check for null device pointers
authorDon Brace <don.brace@microsemi.com>
Fri, 9 Sep 2016 21:30:23 +0000 (16:30 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 14 Sep 2016 18:14:40 +0000 (14:14 -0400)
A device can be deleted causing NULL pointer issues.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hpsa.c

index 332ff1a..97f50c7 100644 (file)
@@ -2388,7 +2388,8 @@ static void hpsa_cmd_free_and_done(struct ctlr_info *h,
                struct CommandList *c, struct scsi_cmnd *cmd)
 {
        hpsa_cmd_resolve_and_free(h, c);
-       cmd->scsi_done(cmd);
+       if (cmd && cmd->scsi_done)
+               cmd->scsi_done(cmd);
 }
 
 static void hpsa_retry_cmd(struct ctlr_info *h, struct CommandList *c)
@@ -2489,6 +2490,12 @@ static void complete_scsi_command(struct CommandList *cp)
        ei = cp->err_info;
        cmd = cp->scsi_cmd;
        h = cp->h;
+
+       if (!cmd->device) {
+               cmd->result = DID_NO_CONNECT << 16;
+               return hpsa_cmd_free_and_done(h, cp, cmd);
+       }
+
        dev = cmd->device->hostdata;
        c2 = &h->ioaccel2_cmd_pool[cp->cmdindex];
 
@@ -2504,8 +2511,15 @@ static void complete_scsi_command(struct CommandList *cp)
        cmd->result = (DID_OK << 16);           /* host byte */
        cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
 
-       if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1)
-               atomic_dec(&cp->phys_disk->ioaccel_cmds_out);
+       if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1) {
+               if (dev->physical_device && dev->expose_device &&
+                       dev->removed) {
+                       cmd->result = DID_NO_CONNECT << 16;
+                       return hpsa_cmd_free_and_done(h, cp, cmd);
+               }
+               if (likely(cp->phys_disk != NULL))
+                       atomic_dec(&cp->phys_disk->ioaccel_cmds_out);
+       }
 
        /*
         * We check for lockup status here as it may be set for