Commit b02b1fbd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "This is a set of four fixes noticed in the merge window.  The aacraid
  one is an optimisation, the mp3sas one fixes a spurious printk, the
  sd_check_events one fixes a theoretical race and the failed zero
  length commands fixes a bug in our completion/retry routines that has
  been causing problems in the field"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  aacraid: do not activate events on non-SRC adapters
  mpt3sas: add missing curly braces
  sd: get disk reference in sd_check_events()
  scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands
parents 1a695a90 787ab6e9
...@@ -620,6 +620,11 @@ struct aac_driver_ident ...@@ -620,6 +620,11 @@ struct aac_driver_ident
*/ */
#define AAC_QUIRK_SCSI_32 0x0020 #define AAC_QUIRK_SCSI_32 0x0020
/*
* SRC based adapters support the AifReqEvent functions
*/
#define AAC_QUIRK_SRC 0x0040
/* /*
* The adapter interface specs all queues to be located in the same * The adapter interface specs all queues to be located in the same
* physically contiguous block. The host structure that defines the * physically contiguous block. The host structure that defines the
......
...@@ -236,10 +236,10 @@ static struct aac_driver_ident aac_drivers[] = { ...@@ -236,10 +236,10 @@ static struct aac_driver_ident aac_drivers[] = {
{ aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Catch All */ { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Catch All */
{ aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */ { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */
{ aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec NEMER/ARK Catch All */ { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec NEMER/ARK Catch All */
{ aac_src_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec PMC Series 6 (Tupelo) */ { aac_src_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 6 (Tupelo) */
{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec PMC Series 7 (Denali) */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 7 (Denali) */
{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec PMC Series 8 */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 8 */
{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec PMC Series 9 */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC } /* Adaptec PMC Series 9 */
}; };
/** /**
...@@ -1299,7 +1299,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1299,7 +1299,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
else else
shost->this_id = shost->max_id; shost->this_id = shost->max_id;
aac_intr_normal(aac, 0, 2, 0, NULL); if (aac_drivers[index].quirks & AAC_QUIRK_SRC)
aac_intr_normal(aac, 0, 2, 0, NULL);
/* /*
* dmb - we may need to move the setting of these parms somewhere else once * dmb - we may need to move the setting of these parms somewhere else once
......
...@@ -7975,13 +7975,14 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ...@@ -7975,13 +7975,14 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
ActiveCableEventData = ActiveCableEventData =
(Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData; (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
if (ActiveCableEventData->ReasonCode == if (ActiveCableEventData->ReasonCode ==
MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d", pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d",
ioc->name, ActiveCableEventData->ReceptacleID); ioc->name, ActiveCableEventData->ReceptacleID);
pr_info("cannot be powered and devices connected to this active cable"); pr_info("cannot be powered and devices connected to this active cable");
pr_info("will not be seen. This active cable"); pr_info("will not be seen. This active cable");
pr_info("requires %d mW of power", pr_info("requires %d mW of power",
ActiveCableEventData->ActiveCablePowerRequirement); ActiveCableEventData->ActiveCablePowerRequirement);
}
break; break;
default: /* ignore the rest */ default: /* ignore the rest */
......
...@@ -821,9 +821,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -821,9 +821,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
} }
/* /*
* If we finished all bytes in the request we are done now. * special case: failed zero length commands always need to
* drop down into the retry code. Otherwise, if we finished
* all bytes in the request we are done now.
*/ */
if (!scsi_end_request(req, error, good_bytes, 0)) if (!(blk_rq_bytes(req) == 0 && error) &&
!scsi_end_request(req, error, good_bytes, 0))
return; return;
/* /*
......
...@@ -1398,11 +1398,15 @@ static int media_not_present(struct scsi_disk *sdkp, ...@@ -1398,11 +1398,15 @@ static int media_not_present(struct scsi_disk *sdkp,
**/ **/
static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
{ {
struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_disk *sdkp = scsi_disk_get(disk);
struct scsi_device *sdp = sdkp->device; struct scsi_device *sdp;
struct scsi_sense_hdr *sshdr = NULL; struct scsi_sense_hdr *sshdr = NULL;
int retval; int retval;
if (!sdkp)
return 0;
sdp = sdkp->device;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
/* /*
...@@ -1459,6 +1463,7 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) ...@@ -1459,6 +1463,7 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
kfree(sshdr); kfree(sshdr);
retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
sdp->changed = 0; sdp->changed = 0;
scsi_disk_put(sdkp);
return retval; return retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment