diff options
author | James Bottomley <James.Bottomley@suse.de> | 2009-11-05 14:33:12 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:01:30 -0500 |
commit | d139b9bd0e52dda14fd13412e7096e68b56d0076 (patch) | |
tree | 518daa6384ff606ec77dd8fe4714ea2f177d92c4 /drivers/scsi | |
parent | 5917290ce9b376866b165d02a5ed88d5ecdb32d0 (diff) |
[SCSI] scsi_lib_dma: fix bug with dma maps on nested scsi objects
Some of our virtual SCSI hosts don't have a proper bus parent at the
top, which can be a problem for doing DMA on them
This patch makes the host device cache a pointer to the physical bus
device and provides an extra API for setting it (the normal API picks
it up from the parent). This patch also modifies the qla2xxx and lpfc
vport logic to use the new DMA host setting API.
Acked-By: James Smart <james.smart@emulex.com>
Cc: Stable Tree <stable@kernel.org>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/hosts.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib_dma.c | 4 |
4 files changed, 15 insertions, 7 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 5fd2da494d08..28a753d796f3 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -180,14 +180,20 @@ void scsi_remove_host(struct Scsi_Host *shost) | |||
180 | EXPORT_SYMBOL(scsi_remove_host); | 180 | EXPORT_SYMBOL(scsi_remove_host); |
181 | 181 | ||
182 | /** | 182 | /** |
183 | * scsi_add_host - add a scsi host | 183 | * scsi_add_host_with_dma - add a scsi host with dma device |
184 | * @shost: scsi host pointer to add | 184 | * @shost: scsi host pointer to add |
185 | * @dev: a struct device of type scsi class | 185 | * @dev: a struct device of type scsi class |
186 | * @dma_dev: dma device for the host | ||
187 | * | ||
188 | * Note: You rarely need to worry about this unless you're in a | ||
189 | * virtualised host environments, so use the simpler scsi_add_host() | ||
190 | * function instead. | ||
186 | * | 191 | * |
187 | * Return value: | 192 | * Return value: |
188 | * 0 on success / != 0 for error | 193 | * 0 on success / != 0 for error |
189 | **/ | 194 | **/ |
190 | int scsi_add_host(struct Scsi_Host *shost, struct device *dev) | 195 | int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, |
196 | struct device *dma_dev) | ||
191 | { | 197 | { |
192 | struct scsi_host_template *sht = shost->hostt; | 198 | struct scsi_host_template *sht = shost->hostt; |
193 | int error = -EINVAL; | 199 | int error = -EINVAL; |
@@ -207,6 +213,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) | |||
207 | 213 | ||
208 | if (!shost->shost_gendev.parent) | 214 | if (!shost->shost_gendev.parent) |
209 | shost->shost_gendev.parent = dev ? dev : &platform_bus; | 215 | shost->shost_gendev.parent = dev ? dev : &platform_bus; |
216 | shost->dma_dev = dma_dev; | ||
210 | 217 | ||
211 | error = device_add(&shost->shost_gendev); | 218 | error = device_add(&shost->shost_gendev); |
212 | if (error) | 219 | if (error) |
@@ -262,7 +269,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) | |||
262 | fail: | 269 | fail: |
263 | return error; | 270 | return error; |
264 | } | 271 | } |
265 | EXPORT_SYMBOL(scsi_add_host); | 272 | EXPORT_SYMBOL(scsi_add_host_with_dma); |
266 | 273 | ||
267 | static void scsi_host_dev_release(struct device *dev) | 274 | static void scsi_host_dev_release(struct device *dev) |
268 | { | 275 | { |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 562d8cee874b..f913f1e93635 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2408,7 +2408,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
2408 | vport->els_tmofunc.function = lpfc_els_timeout; | 2408 | vport->els_tmofunc.function = lpfc_els_timeout; |
2409 | vport->els_tmofunc.data = (unsigned long)vport; | 2409 | vport->els_tmofunc.data = (unsigned long)vport; |
2410 | 2410 | ||
2411 | error = scsi_add_host(shost, dev); | 2411 | error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); |
2412 | if (error) | 2412 | if (error) |
2413 | goto out_put_shost; | 2413 | goto out_put_shost; |
2414 | 2414 | ||
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fbcb82a2f7f4..21e2bc4d7401 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1654,7 +1654,8 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1654 | fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); | 1654 | fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | if (scsi_add_host(vha->host, &fc_vport->dev)) { | 1657 | if (scsi_add_host_with_dma(vha->host, &fc_vport->dev, |
1658 | &ha->pdev->dev)) { | ||
1658 | DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n", | 1659 | DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n", |
1659 | vha->host_no, vha->vp_idx)); | 1660 | vha->host_no, vha->vp_idx)); |
1660 | goto vport_create_failed_2; | 1661 | goto vport_create_failed_2; |
diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c index ac6855cd2657..dcd128583b89 100644 --- a/drivers/scsi/scsi_lib_dma.c +++ b/drivers/scsi/scsi_lib_dma.c | |||
@@ -23,7 +23,7 @@ int scsi_dma_map(struct scsi_cmnd *cmd) | |||
23 | int nseg = 0; | 23 | int nseg = 0; |
24 | 24 | ||
25 | if (scsi_sg_count(cmd)) { | 25 | if (scsi_sg_count(cmd)) { |
26 | struct device *dev = cmd->device->host->shost_gendev.parent; | 26 | struct device *dev = cmd->device->host->dma_dev; |
27 | 27 | ||
28 | nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), | 28 | nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), |
29 | cmd->sc_data_direction); | 29 | cmd->sc_data_direction); |
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(scsi_dma_map); | |||
41 | void scsi_dma_unmap(struct scsi_cmnd *cmd) | 41 | void scsi_dma_unmap(struct scsi_cmnd *cmd) |
42 | { | 42 | { |
43 | if (scsi_sg_count(cmd)) { | 43 | if (scsi_sg_count(cmd)) { |
44 | struct device *dev = cmd->device->host->shost_gendev.parent; | 44 | struct device *dev = cmd->device->host->dma_dev; |
45 | 45 | ||
46 | dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), | 46 | dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), |
47 | cmd->sc_data_direction); | 47 | cmd->sc_data_direction); |