summaryrefslogtreecommitdiff
path: root/drivers/scsi/gdth.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 11:25:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 11:25:31 -0700
commit2cca775baecbfede2fec20c99add709232311fe7 (patch)
treeb0eefe80881d263ba7976174144ae4e9cf238425 /drivers/scsi/gdth.c
parenteddeb0e2d863e3941d8768e70cb50c6120e61fa0 (diff)
parent94795b61e84994a3b058f92d041d1fb3d869c7d5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (137 commits) [SCSI] iscsi: bidi support for iscsi_tcp [SCSI] iscsi: bidi support at the generic libiscsi level [SCSI] iscsi: extended cdb support [SCSI] zfcp: Fix error handling for blocked unit for send FCP command [SCSI] zfcp: Remove zfcp_erp_wait from slave destory handler to fix deadlock [SCSI] zfcp: fix 31 bit compile warnings [SCSI] bsg: no need to set BSG_F_BLOCK bit in bsg_complete_all_commands [SCSI] bsg: remove minor in struct bsg_device [SCSI] bsg: use better helper list functions [SCSI] bsg: replace kobject_get with blk_get_queue [SCSI] bsg: takes a ref to struct device in fops->open [SCSI] qla1280: remove version check [SCSI] libsas: fix endianness bug in sas_ata [SCSI] zfcp: fix compiler warning caused by poking inside new semaphore (linux-next) [SCSI] aacraid: Do not describe check_reset parameter with its value [SCSI] aacraid: Fix down_interruptible() to check the return value [SCSI] sun3_scsi_vme: add MODULE_LICENSE [SCSI] st: rename flush_write_buffer() [SCSI] tgt: use KMEM_CACHE macro [SCSI] initio: fix big endian problems for auto request sense ...
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r--drivers/scsi/gdth.c320
1 files changed, 132 insertions, 188 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 0b2080d33575..c6d6e7c6559a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -85,10 +85,10 @@
/* The meaning of the Scsi_Pointer members in this driver is as follows:
* ptr: Chaining
- * this_residual: gdth_bufflen
- * buffer: gdth_sglist
+ * this_residual: unused
+ * buffer: unused
* dma_handle: unused
- * buffers_residual: gdth_sg_count
+ * buffers_residual: unused
* Status: unused
* Message: unused
* have_data_in: unused
@@ -372,47 +372,6 @@ static const struct file_operations gdth_fops = {
.release = gdth_close,
};
-/*
- * gdth scsi_command access wrappers.
- * below 6 functions are used throughout the driver to access scsi_command's
- * io parameters. The reason we do not use the regular accessors from
- * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for
- * llds to directly set scsi_cmnd's IO members. This driver will use SCp
- * members for IO parameters, and will copy scsi_cmnd's members to Scp
- * members in queuecommand. For internal commands through gdth_execute()
- * SCp's members will be set directly.
- */
-static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd)
-{
- return (unsigned)cmd->SCp.this_residual;
-}
-
-static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen)
-{
- cmd->SCp.this_residual = bufflen;
-}
-
-static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd)
-{
- return (unsigned)cmd->SCp.buffers_residual;
-}
-
-static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count)
-{
- cmd->SCp.buffers_residual = sg_count;
-}
-
-static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd)
-{
- return cmd->SCp.buffer;
-}
-
-static inline void gdth_set_sglist(struct scsi_cmnd *cmd,
- struct scatterlist *sglist)
-{
- cmd->SCp.buffer = sglist;
-}
-
#include "gdth_proc.h"
#include "gdth_proc.c"
@@ -591,125 +550,111 @@ static int __init gdth_search_isa(ulong32 bios_adr)
#endif /* CONFIG_ISA */
#ifdef CONFIG_PCI
-static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
- ushort vendor, ushort dev);
+static bool gdth_pci_registered;
-static int __init gdth_search_pci(gdth_pci_str *pcistr)
+static bool gdth_search_vortex(ushort device)
{
- ushort device, cnt;
-
- TRACE(("gdth_search_pci()\n"));
-
- cnt = 0;
- for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
- gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
- for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP;
- device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
- gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
- gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX,
- PCI_DEVICE_ID_VORTEX_GDTNEWRX);
- gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX,
- PCI_DEVICE_ID_VORTEX_GDTNEWRX2);
- gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_SRC);
- gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_SRC_XSCALE);
- return cnt;
+ if (device <= PCI_DEVICE_ID_VORTEX_GDT6555)
+ return true;
+ if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP &&
+ device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP)
+ return true;
+ if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX ||
+ device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2)
+ return true;
+ return false;
}
+static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out);
+static int gdth_pci_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void gdth_pci_remove_one(struct pci_dev *pdev);
+static void gdth_remove_one(gdth_ha_str *ha);
+
/* Vortex only makes RAID controllers.
* We do not really want to specify all 550 ids here, so wildcard match.
*/
-static struct pci_device_id gdthtable[] __maybe_unused = {
- {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
- {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID},
- {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID},
- {0}
+static const struct pci_device_id gdthtable[] = {
+ { PCI_VDEVICE(VORTEX, PCI_ANY_ID) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) },
+ { } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, gdthtable);
+
+static struct pci_driver gdth_pci_driver = {
+ .name = "gdth",
+ .id_table = gdthtable,
+ .probe = gdth_pci_init_one,
+ .remove = gdth_pci_remove_one,
};
-MODULE_DEVICE_TABLE(pci,gdthtable);
-static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
- ushort vendor, ushort device)
+static void gdth_pci_remove_one(struct pci_dev *pdev)
{
- ulong base0, base1, base2;
- struct pci_dev *pdev;
+ gdth_ha_str *ha = pci_get_drvdata(pdev);
+
+ pci_set_drvdata(pdev, NULL);
+
+ list_del(&ha->list);
+ gdth_remove_one(ha);
+
+ pci_disable_device(pdev);
+}
+
+static int gdth_pci_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ ushort vendor = pdev->vendor;
+ ushort device = pdev->device;
+ ulong base0, base1, base2;
+ int rc;
+ gdth_pci_str gdth_pcistr;
+ gdth_ha_str *ha = NULL;
- TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
- *cnt, vendor, device));
+ TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
+ gdth_ctr_count, vendor, device));
- pdev = NULL;
- while ((pdev = pci_get_device(vendor, device, pdev))
- != NULL) {
- if (pci_enable_device(pdev))
- continue;
- if (*cnt >= MAXHA) {
- pci_dev_put(pdev);
- return;
- }
+ memset(&gdth_pcistr, 0, sizeof(gdth_pcistr));
+
+ if (vendor == PCI_VENDOR_ID_VORTEX && !gdth_search_vortex(device))
+ return -ENODEV;
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ if (gdth_ctr_count >= MAXHA)
+ return -EBUSY;
/* GDT PCI controller found, resources are already in pdev */
- pcistr[*cnt].pdev = pdev;
- pcistr[*cnt].irq = pdev->irq;
+ gdth_pcistr.pdev = pdev;
base0 = pci_resource_flags(pdev, 0);
base1 = pci_resource_flags(pdev, 1);
base2 = pci_resource_flags(pdev, 2);
if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
if (!(base0 & IORESOURCE_MEM))
- continue;
- pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
+ return -ENODEV;
+ gdth_pcistr.dpmem = pci_resource_start(pdev, 0);
} else { /* GDT6110, GDT6120, .. */
if (!(base0 & IORESOURCE_MEM) ||
!(base2 & IORESOURCE_MEM) ||
!(base1 & IORESOURCE_IO))
- continue;
- pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
- pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
- pcistr[*cnt].io = pci_resource_start(pdev, 1);
+ return -ENODEV;
+ gdth_pcistr.dpmem = pci_resource_start(pdev, 2);
+ gdth_pcistr.io = pci_resource_start(pdev, 1);
}
TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
- pcistr[*cnt].pdev->bus->number,
- PCI_SLOT(pcistr[*cnt].pdev->devfn),
- pcistr[*cnt].irq, pcistr[*cnt].dpmem));
- (*cnt)++;
- }
-}
+ gdth_pcistr.pdev->bus->number,
+ PCI_SLOT(gdth_pcistr.pdev->devfn),
+ gdth_pcistr.irq,
+ gdth_pcistr.dpmem));
-static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt)
-{
- gdth_pci_str temp;
- int i, changed;
-
- TRACE(("gdth_sort_pci() cnt %d\n",cnt));
- if (cnt == 0)
- return;
+ rc = gdth_pci_probe_one(&gdth_pcistr, &ha);
+ if (rc)
+ return rc;
- do {
- changed = FALSE;
- for (i = 0; i < cnt-1; ++i) {
- if (!reverse_scan) {
- if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) ||
- (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
- PCI_SLOT(pcistr[i].pdev->devfn) >
- PCI_SLOT(pcistr[i+1].pdev->devfn))) {
- temp = pcistr[i];
- pcistr[i] = pcistr[i+1];
- pcistr[i+1] = temp;
- changed = TRUE;
- }
- } else {
- if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) ||
- (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
- PCI_SLOT(pcistr[i].pdev->devfn) <
- PCI_SLOT(pcistr[i+1].pdev->devfn))) {
- temp = pcistr[i];
- pcistr[i] = pcistr[i+1];
- pcistr[i+1] = temp;
- changed = TRUE;
- }
- }
- }
- } while (changed);
+ return 0;
}
#endif /* CONFIG_PCI */
@@ -909,7 +854,8 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
#endif /* CONFIG_ISA */
#ifdef CONFIG_PCI
-static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
+static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
+ gdth_ha_str *ha)
{
register gdt6_dpram_str __iomem *dp6_ptr;
register gdt6c_dpram_str __iomem *dp6c_ptr;
@@ -921,14 +867,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
TRACE(("gdth_init_pci()\n"));
- if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL)
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL)
ha->oem_id = OEM_ID_INTEL;
else
ha->oem_id = OEM_ID_ICP;
- ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8);
- ha->stype = (ulong32)pcistr->pdev->device;
- ha->irq = pcistr->irq;
- ha->pdev = pcistr->pdev;
+ ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8);
+ ha->stype = (ulong32)pdev->device;
+ ha->irq = pdev->irq;
+ ha->pdev = pdev;
if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */
TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -956,8 +902,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
continue;
}
iounmap(ha->brd);
- pci_write_config_dword(pcistr->pdev,
- PCI_BASE_ADDRESS_0, i);
+ pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i);
ha->brd = ioremap(i, sizeof(gdt6_dpram_str));
if (ha->brd == NULL) {
printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
@@ -1066,8 +1011,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
continue;
}
iounmap(ha->brd);
- pci_write_config_dword(pcistr->pdev,
- PCI_BASE_ADDRESS_2, i);
+ pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, i);
ha->brd = ioremap(i, sizeof(gdt6c_dpram_str));
if (ha->brd == NULL) {
printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
@@ -1159,16 +1103,16 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
}
/* manipulate config. space to enable DPMEM, start RP controller */
- pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
+ pci_read_config_word(pdev, PCI_COMMAND, &command);
command |= 6;
- pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
- if (pci_resource_start(pcistr->pdev, 8) == 1UL)
- pci_resource_start(pcistr->pdev, 8) = 0UL;
+ pci_write_config_word(pdev, PCI_COMMAND, command);
+ if (pci_resource_start(pdev, 8) == 1UL)
+ pci_resource_start(pdev, 8) = 0UL;
i = 0xFEFF0001UL;
- pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS, i);
gdth_delay(1);
- pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
- pci_resource_start(pcistr->pdev, 8));
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
+ pci_resource_start(pdev, 8));
dp6m_ptr = ha->brd;
@@ -1195,8 +1139,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
continue;
}
iounmap(ha->brd);
- pci_write_config_dword(pcistr->pdev,
- PCI_BASE_ADDRESS_0, i);
+ pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i);
ha->brd = ioremap(i, sizeof(gdt6m_dpram_str));
if (ha->brd == NULL) {
printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
@@ -2353,12 +2296,12 @@ static void gdth_next(gdth_ha_str *ha)
static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
char *buffer, ushort count)
{
- ushort cpcount,i, max_sg = gdth_sg_count(scp);
+ ushort cpcount,i, max_sg = scsi_sg_count(scp);
ushort cpsum,cpnow;
struct scatterlist *sl;
char *address;
- cpcount = min_t(ushort, count, gdth_bufflen(scp));
+ cpcount = min_t(ushort, count, scsi_bufflen(scp));
if (cpcount) {
cpsum=0;
@@ -2366,7 +2309,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
unsigned long flags;
cpnow = (ushort)sl->length;
TRACE(("copy_internal() now %d sum %d count %d %d\n",
- cpnow, cpsum, cpcount, gdth_bufflen(scp)));
+ cpnow, cpsum, cpcount, scsi_bufflen(scp)));
if (cpsum+cpnow > cpcount)
cpnow = cpcount - cpsum;
cpsum += cpnow;
@@ -2589,10 +2532,10 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive)
cmdp->u.cache.BlockCnt = blockcnt;
}
- if (gdth_bufflen(scp)) {
+ if (scsi_bufflen(scp)) {
cmndinfo->dma_dir = (read_write == 1 ?
PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
- sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
+ sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
cmndinfo->dma_dir);
if (mode64) {
struct scatterlist *sl;
@@ -2739,7 +2682,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
cmdp->u.raw64.lun = l;
cmdp->u.raw64.bus = b;
cmdp->u.raw64.priority = 0;
- cmdp->u.raw64.sdlen = gdth_bufflen(scp);
+ cmdp->u.raw64.sdlen = scsi_bufflen(scp);
cmdp->u.raw64.sense_len = 16;
cmdp->u.raw64.sense_data = sense_paddr;
cmdp->u.raw64.direction =
@@ -2756,7 +2699,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
cmdp->u.raw.bus = b;
cmdp->u.raw.priority = 0;
cmdp->u.raw.link_p = 0;
- cmdp->u.raw.sdlen = gdth_bufflen(scp);
+ cmdp->u.raw.sdlen = scsi_bufflen(scp);
cmdp->u.raw.sense_len = 16;
cmdp->u.raw.sense_data = sense_paddr;
cmdp->u.raw.direction =
@@ -2765,9 +2708,9 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
cmdp->u.raw.sg_ranz = 0;
}
- if (gdth_bufflen(scp)) {
+ if (scsi_bufflen(scp)) {
cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL;
- sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
+ sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
cmndinfo->dma_dir);
if (mode64) {
struct scatterlist *sl;
@@ -3388,8 +3331,8 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index,
/* retry */
return 2;
}
- if (gdth_bufflen(scp))
- pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
+ if (scsi_bufflen(scp))
+ pci_unmap_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
cmndinfo->dma_dir);
if (cmndinfo->sense_paddr)
@@ -4031,10 +3974,6 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
gdth_update_timeout(scp, scp->timeout_per_command * 6);
cmndinfo->priority = DEFAULT_PRI;
- gdth_set_bufflen(scp, scsi_bufflen(scp));
- gdth_set_sg_count(scp, scsi_sg_count(scp));
- gdth_set_sglist(scp, scsi_sglist(scp));
-
return __gdth_queuecommand(ha, scp, cmndinfo);
}
@@ -4955,12 +4894,16 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
#endif /* CONFIG_EISA */
#ifdef CONFIG_PCI
-static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
+static int gdth_pci_probe_one(gdth_pci_str *pcistr,
+ gdth_ha_str **ha_out)
{
struct Scsi_Host *shp;
gdth_ha_str *ha;
dma_addr_t scratch_dma_handle = 0;
int error, i;
+ struct pci_dev *pdev = pcistr->pdev;
+
+ *ha_out = NULL;
shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
if (!shp)
@@ -4968,13 +4911,13 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
ha = shost_priv(shp);
error = -ENODEV;
- if (!gdth_init_pci(&pcistr[ctr],ha))
+ if (!gdth_init_pci(pdev, pcistr, ha))
goto out_host_put;
/* controller found and initialized */
printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n",
- pcistr[ctr].pdev->bus->number,
- PCI_SLOT(pcistr[ctr].pdev->devfn),
+ pdev->bus->number,
+ PCI_SLOT(pdev->devfn),
ha->irq);
error = request_irq(ha->irq, gdth_interrupt,
@@ -5019,7 +4962,7 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
ha->scratch_busy = FALSE;
ha->req_first = NULL;
- ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
+ ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
if (max_ids > 0 && max_ids < ha->tid_cnt)
ha->tid_cnt = max_ids;
for (i = 0; i < GDTH_MAXCMDS; ++i)
@@ -5039,16 +4982,16 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
/* 64-bit DMA only supported from FW >= x.43 */
if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) ||
!ha->dma64_support) {
- if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "GDT-PCI %d: "
"Unable to set 32-bit DMA\n", ha->hanum);
goto out_free_coal_stat;
}
} else {
shp->max_cmd_len = 16;
- if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum);
- } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) {
+ } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "GDT-PCI %d: "
"Unable to set 64/32-bit DMA\n", ha->hanum);
goto out_free_coal_stat;
@@ -5062,13 +5005,17 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
spin_lock_init(&ha->smp_lock);
gdth_enable_int(ha);
- error = scsi_add_host(shp, &pcistr[ctr].pdev->dev);
+ error = scsi_add_host(shp, &pdev->dev);
if (error)
goto out_free_coal_stat;
list_add_tail(&ha->list, &gdth_instances);
+ pci_set_drvdata(ha->pdev, ha);
+
scsi_scan_host(shp);
+ *ha_out = ha;
+
return 0;
out_free_coal_stat:
@@ -5185,16 +5132,8 @@ static int __init gdth_init(void)
#ifdef CONFIG_PCI
/* scanning for PCI controllers */
- {
- gdth_pci_str pcistr[MAXHA];
- int cnt,ctr;
-
- cnt = gdth_search_pci(pcistr);
- printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt);
- gdth_sort_pci(pcistr,cnt);
- for (ctr = 0; ctr < cnt; ++ctr)
- gdth_pci_probe_one(pcistr, ctr);
- }
+ if (pci_register_driver(&gdth_pci_driver) == 0)
+ gdth_pci_registered = true;
#endif /* CONFIG_PCI */
TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
@@ -5227,6 +5166,11 @@ static void __exit gdth_exit(void)
del_timer_sync(&gdth_timer);
#endif
+#ifdef CONFIG_PCI
+ if (gdth_pci_registered)
+ pci_unregister_driver(&gdth_pci_driver);
+#endif
+
list_for_each_entry(ha, &gdth_instances, list)
gdth_remove_one(ha);
}