Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

…it/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "This is a set of three fixes for data corruption (libsas task file),
  oops causing (NULL in scsi_cmd_to_driver) and driver failure (bnx2i).
  The oops caused by the NULL in scsi_cmd_to_driver() manifests in
  scsi_eh_send_cmd() and has been seen by several people now.

  Signed-off-by: James Bottomley <JBottomley@Parallels.com>"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  [SCSI] bnx2i: Removed the reference to the netdev->base_addr
  [SCSI] libsas: fix taskfile corruption in sas_ata_qc_fill_rtf
  [SCSI] Fix NULL dereferences in scsi_cmd_to_driver
  • Loading branch information...
commit 5f8ebd36f7dd95ec97aec82d5907522dc54e85ba 2 parents 8a76e53 + a771718
Linus Torvalds torvalds authored
2  drivers/scsi/aic94xx/aic94xx_task.c
@@ -201,7 +201,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb,
201 201
202 202 if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
203 203 resp->frame_len = le16_to_cpu(*(__le16 *)(r+6));
204   - memcpy(&resp->ending_fis[0], r+16, 24);
  204 + memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE);
205 205 ts->buf_valid_size = sizeof(*resp);
206 206 }
207 207 }
1  drivers/scsi/bnx2i/bnx2i.h
@@ -350,6 +350,7 @@ struct bnx2i_hba {
350 350 struct pci_dev *pcidev;
351 351 struct net_device *netdev;
352 352 void __iomem *regview;
  353 + resource_size_t reg_base;
353 354
354 355 u32 age;
355 356 unsigned long cnic_dev_type;
3  drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -2724,7 +2724,6 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep)
2724 2724 goto arm_cq;
2725 2725 }
2726 2726
2727   - reg_base = ep->hba->netdev->base_addr;
2728 2727 if ((test_bit(BNX2I_NX2_DEV_5709, &ep->hba->cnic_dev_type)) &&
2729 2728 (ep->hba->mail_queue_access == BNX2I_MQ_BIN_MODE)) {
2730 2729 config2 = REG_RD(ep->hba, BNX2_MQ_CONFIG2);
@@ -2740,7 +2739,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep)
2740 2739 /* 5709 device in normal node and 5706/5708 devices */
2741 2740 reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num);
2742 2741
2743   - ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off,
  2742 + ep->qp.ctx_base = ioremap_nocache(ep->hba->reg_base + reg_off,
2744 2743 MB_KERNEL_CTX_SIZE);
2745 2744 if (!ep->qp.ctx_base)
2746 2745 return -ENOMEM;
10 drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -811,13 +811,13 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
811 811 bnx2i_identify_device(hba);
812 812 bnx2i_setup_host_queue_size(hba, shost);
813 813
  814 + hba->reg_base = pci_resource_start(hba->pcidev, 0);
814 815 if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) {
815   - hba->regview = ioremap_nocache(hba->netdev->base_addr,
816   - BNX2_MQ_CONFIG2);
  816 + hba->regview = pci_iomap(hba->pcidev, 0, BNX2_MQ_CONFIG2);
817 817 if (!hba->regview)
818 818 goto ioreg_map_err;
819 819 } else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) {
820   - hba->regview = ioremap_nocache(hba->netdev->base_addr, 4096);
  820 + hba->regview = pci_iomap(hba->pcidev, 0, 4096);
821 821 if (!hba->regview)
822 822 goto ioreg_map_err;
823 823 }
@@ -884,7 +884,7 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
884 884 bnx2i_free_mp_bdt(hba);
885 885 mp_bdt_mem_err:
886 886 if (hba->regview) {
887   - iounmap(hba->regview);
  887 + pci_iounmap(hba->pcidev, hba->regview);
888 888 hba->regview = NULL;
889 889 }
890 890 ioreg_map_err:
@@ -910,7 +910,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba)
910 910 pci_dev_put(hba->pcidev);
911 911
912 912 if (hba->regview) {
913   - iounmap(hba->regview);
  913 + pci_iounmap(hba->pcidev, hba->regview);
914 914 hba->regview = NULL;
915 915 }
916 916 bnx2i_free_mp_bdt(hba);
12 drivers/scsi/libsas/sas_ata.c
@@ -139,12 +139,12 @@ static void sas_ata_task_done(struct sas_task *task)
139 139 if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
140 140 ((stat->stat == SAM_STAT_CHECK_CONDITION &&
141 141 dev->sata_dev.command_set == ATAPI_COMMAND_SET))) {
142   - ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
  142 + memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE);
143 143
144 144 if (!link->sactive) {
145   - qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
  145 + qc->err_mask |= ac_err_mask(dev->sata_dev.fis[2]);
146 146 } else {
147   - link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command);
  147 + link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.fis[2]);
148 148 if (unlikely(link->eh_info.err_mask))
149 149 qc->flags |= ATA_QCFLAG_FAILED;
150 150 }
@@ -161,8 +161,8 @@ static void sas_ata_task_done(struct sas_task *task)
161 161 qc->flags |= ATA_QCFLAG_FAILED;
162 162 }
163 163
164   - dev->sata_dev.tf.feature = 0x04; /* status err */
165   - dev->sata_dev.tf.command = ATA_ERR;
  164 + dev->sata_dev.fis[3] = 0x04; /* status err */
  165 + dev->sata_dev.fis[2] = ATA_ERR;
166 166 }
167 167 }
168 168
@@ -269,7 +269,7 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc)
269 269 {
270 270 struct domain_device *dev = qc->ap->private_data;
271 271
272   - memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf));
  272 + ata_tf_from_fis(dev->sata_dev.fis, &qc->result_tf);
273 273 return true;
274 274 }
275 275
6 include/scsi/libsas.h
@@ -163,6 +163,8 @@ enum ata_command_set {
163 163 ATAPI_COMMAND_SET = 1,
164 164 };
165 165
  166 +#define ATA_RESP_FIS_SIZE 24
  167 +
166 168 struct sata_device {
167 169 enum ata_command_set command_set;
168 170 struct smp_resp rps_resp; /* report_phy_sata_resp */
@@ -171,7 +173,7 @@ struct sata_device {
171 173
172 174 struct ata_port *ap;
173 175 struct ata_host ata_host;
174   - struct ata_taskfile tf;
  176 + u8 fis[ATA_RESP_FIS_SIZE];
175 177 };
176 178
177 179 enum {
@@ -537,7 +539,7 @@ enum exec_status {
537 539 */
538 540 struct ata_task_resp {
539 541 u16 frame_len;
540   - u8 ending_fis[24]; /* dev to host or data-in */
  542 + u8 ending_fis[ATA_RESP_FIS_SIZE]; /* dev to host or data-in */
541 543 };
542 544
543 545 #define SAS_STATUS_BUF_SIZE 96
8 include/scsi/scsi_cmnd.h
@@ -134,10 +134,16 @@ struct scsi_cmnd {
134 134
135 135 static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
136 136 {
  137 + struct scsi_driver **sdp;
  138 +
137 139 if (!cmd->request->rq_disk)
138 140 return NULL;
139 141
140   - return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
  142 + sdp = (struct scsi_driver **)cmd->request->rq_disk->private_data;
  143 + if (!sdp)
  144 + return NULL;
  145 +
  146 + return *sdp;
141 147 }
142 148
143 149 extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);

0 comments on commit 5f8ebd3

Please sign in to comment.
Something went wrong with that request. Please try again.