aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorEd Lin <ed.lin@promise.com>2009-09-29 02:58:17 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:25 -0400
commitcbacfb5fd9a4689b55157753b8ba4455415fb85c (patch)
treebb0a6ed9efd197ef45c5bbedfd4cd04c07fdc884 /drivers/scsi
parent080bb708ad8f21ea743d1a9233fbc62af0feb10b (diff)
[SCSI] stex: add small dma buffer support
The controllers of st_seq and st_vsc type can work if only small dma buffer is available, with a reduced firmware feature set. Add support for this case. Signed-off-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/stex.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 09fa8861fc58..af5bafcccf1f 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -160,6 +160,7 @@ enum {
160 INQUIRY_EVPD = 0x01, 160 INQUIRY_EVPD = 0x01,
161 161
162 ST_ADDITIONAL_MEM = 0x200000, 162 ST_ADDITIONAL_MEM = 0x200000,
163 ST_ADDITIONAL_MEM_MIN = 0x80000,
163}; 164};
164 165
165struct st_sgitem { 166struct st_sgitem {
@@ -1001,7 +1002,7 @@ static int stex_common_handshake(struct st_hba *hba)
1001 h->partner_type = HMU_PARTNER_TYPE; 1002 h->partner_type = HMU_PARTNER_TYPE;
1002 if (hba->extra_offset) { 1003 if (hba->extra_offset) {
1003 h->extra_offset = cpu_to_le32(hba->extra_offset); 1004 h->extra_offset = cpu_to_le32(hba->extra_offset);
1004 h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); 1005 h->extra_size = cpu_to_le32(hba->dma_size - hba->extra_offset);
1005 } else 1006 } else
1006 h->extra_offset = h->extra_size = 0; 1007 h->extra_offset = h->extra_size = 0;
1007 1008
@@ -1528,10 +1529,24 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1528 hba->dma_mem = dma_alloc_coherent(&pdev->dev, 1529 hba->dma_mem = dma_alloc_coherent(&pdev->dev,
1529 hba->dma_size, &hba->dma_handle, GFP_KERNEL); 1530 hba->dma_size, &hba->dma_handle, GFP_KERNEL);
1530 if (!hba->dma_mem) { 1531 if (!hba->dma_mem) {
1531 err = -ENOMEM; 1532 /* Retry minimum coherent mapping for st_seq and st_vsc */
1532 printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n", 1533 if (hba->cardtype == st_seq ||
1533 pci_name(pdev)); 1534 (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) {
1534 goto out_iounmap; 1535 printk(KERN_WARNING DRV_NAME
1536 "(%s): allocating min buffer for controller\n",
1537 pci_name(pdev));
1538 hba->dma_size = hba->extra_offset
1539 + ST_ADDITIONAL_MEM_MIN;
1540 hba->dma_mem = dma_alloc_coherent(&pdev->dev,
1541 hba->dma_size, &hba->dma_handle, GFP_KERNEL);
1542 }
1543
1544 if (!hba->dma_mem) {
1545 err = -ENOMEM;
1546 printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n",
1547 pci_name(pdev));
1548 goto out_iounmap;
1549 }
1535 } 1550 }
1536 1551
1537 hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL); 1552 hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL);