extractedLnx/linux-2.2.26/drivers/scsi/aic7xxx.c_aic7xxx_detect.c
int
aic7xxx_detect(Scsi_Host_Template *template)
{
struct aic7xxx_host *temp_p = NULL;
struct aic7xxx_host *current_p = NULL;
struct aic7xxx_host *list_p = NULL;
int found = 0;
#if defined(__i386__) || defined(__alpha__)
ahc_flag_type flags = 0;
int type;
#endif
unsigned char sxfrctl1;
#if defined(__i386__) || defined(__alpha__)
unsigned char hcntrl, hostconf;
unsigned int slot, base;
#endif
#ifdef MODULE
/*
* If we are called as a module, the aic7xxx pointer may not be null
* and it would point to our bootup string, just like on the lilo
* command line. IF not NULL, then process this config string with
* aic7xxx_setup
*/
if(aic7xxx)
aic7xxx_setup(aic7xxx, NULL);
if(dummy_buffer[0] != 'P')
printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
"/scsi/README.aic7xxx\n"
"aic7xxx: to see the proper way to specify options to the aic7xxx "
"module\n"
"aic7xxx: Specifically, don't use any commas when passing arguments to\n"
"aic7xxx: insmod or else it might trash certain memory areas.\n");
#endif
template->proc_dir = &proc_scsi_aic7xxx;
template->sg_tablesize = AIC7XXX_MAX_SG;
#ifdef CONFIG_PCI
/*
* PCI-bus probe.
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
if (pci_present())
#else
if (pcibios_present())
#endif
{
struct
{
unsigned short vendor_id;
unsigned short device_id;
ahc_chip chip;
ahc_flag_type flags;
ahc_feature features;
int board_name_index;
unsigned short seeprom_size;
unsigned short seeprom_type;
} const aic_pdevs[] = {
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7810, AHC_NONE,
AHC_FNONE, AHC_FENONE, 1,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7850, AHC_AIC7850,
AHC_PAGESCBS, AHC_AIC7850_FE, 5,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7855, AHC_AIC7850,
AHC_PAGESCBS, AHC_AIC7850_FE, 6,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7821, AHC_AIC7860,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7860_FE, 7,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_3860, AHC_AIC7860,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7860_FE, 7,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_38602, AHC_AIC7860,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7860_FE, 7,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7860, AHC_AIC7860,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MOTHERBOARD,
AHC_AIC7860_FE, 7,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7861, AHC_AIC7860,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7860_FE, 8,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7870, AHC_AIC7870,
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MOTHERBOARD,
AHC_AIC7870_FE, 9,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7871, AHC_AIC7870,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 10,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7872, AHC_AIC7870,
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7870_FE, 11,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7873, AHC_AIC7870,
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7870_FE, 12,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7874, AHC_AIC7870,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 13,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7880, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MOTHERBOARD,
AHC_AIC7880_FE, 14,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7881, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 15,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7882, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7880_FE, 16,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7883, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7880_FE, 17,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7884, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7885, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7886, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7887, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE | AHC_NEW_AUTOTERM, 19,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7888, AHC_AIC7880,
AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7895, AHC_AIC7895,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7895_FE, 20,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890, AHC_AIC7890,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7890_FE, 21,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890B, AHC_AIC7890,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7890_FE, 21,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2930U2, AHC_AIC7890,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7890_FE, 22,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2940U2, AHC_AIC7890,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7890_FE, 23,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7896, AHC_AIC7896,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7896_FE, 24,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3940U2, AHC_AIC7896,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7896_FE, 25,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3950U2D, AHC_AIC7896,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7896_FE, 26,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_1480A, AHC_AIC7860,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_NO_STPWEN,
AHC_AIC7860_FE, 27,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892A, AHC_AIC7892,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7892_FE, 28,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892B, AHC_AIC7892,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7892_FE, 28,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892D, AHC_AIC7892,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7892_FE, 28,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892P, AHC_AIC7892,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
AHC_AIC7892_FE, 28,
32, C46 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899A, AHC_AIC7899,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7899_FE, 29,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899B, AHC_AIC7899,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7899_FE, 29,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899D, AHC_AIC7899,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7899_FE, 29,
32, C56_66 },
{PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899P, AHC_AIC7899,
AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
AHC_AIC7899_FE, 29,
32, C56_66 },
};
unsigned short command;
unsigned int devconfig, i, oldverbose;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
struct pci_dev *pdev = NULL;
#else
int index;
unsigned int piobase, mmapbase;
unsigned char pci_bus, pci_devfn, pci_irq;
#endif
for (i = 0; i < NUMBER(aic_pdevs); i++)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
pdev = NULL;
while ((pdev = pci_find_device(aic_pdevs[i].vendor_id,
aic_pdevs[i].device_id,
pdev)))
#else
index = 0;
while (!(pcibios_find_device(aic_pdevs[i].vendor_id,
aic_pdevs[i].device_id,
index++, &pci_bus, &pci_devfn)) )
#endif
{
if ( i == 0 ) /* We found one, but it's the 7810 RAID cont. */
{
if (aic7xxx_verbose & (VERBOSE_PROBE|VERBOSE_PROBE2))
{
printk(KERN_INFO "aic7xxx: The 7810 RAID controller is not "
"supported by\n");
printk(KERN_INFO " this driver, we are ignoring it.\n");
}
}
else if ( (temp_p = kmalloc(sizeof(struct aic7xxx_host),
GFP_ATOMIC)) != NULL )
{
memset(temp_p, 0, sizeof(struct aic7xxx_host));
temp_p->chip = aic_pdevs[i].chip | AHC_PCI;
temp_p->flags = aic_pdevs[i].flags;
temp_p->features = aic_pdevs[i].features;
temp_p->board_name_index = aic_pdevs[i].board_name_index;
temp_p->sc_size = aic_pdevs[i].seeprom_size;
temp_p->sc_type = aic_pdevs[i].seeprom_type;
/*
* Read sundry information from PCI BIOS.
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
temp_p->irq = pdev->irq;
temp_p->pdev = pdev;
temp_p->pci_bus = pdev->bus->number;
temp_p->pci_device_fn = pdev->devfn;
temp_p->base = pdev->base_address[0];
temp_p->mbase = pdev->base_address[1];
temp_p->base &= PCI_BASE_ADDRESS_IO_MASK;
temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
current_p = list_p;
while(current_p && temp_p)
{
if ( ((current_p->pci_bus == temp_p->pci_bus) &&
(current_p->pci_device_fn == temp_p->pci_device_fn)) ||
(temp_p->base && (current_p->base == temp_p->base)) ||
(temp_p->mbase && (current_p->mbase == temp_p->mbase)) )
{
/* duplicate PCI entry, skip it */
kfree(temp_p);
temp_p = NULL;
}
current_p = current_p->next;
}
if ( temp_p == NULL )
continue;
if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
pci_read_config_word(pdev, PCI_COMMAND, &command);
if (aic7xxx_verbose & VERBOSE_PROBE2)
{
printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
(int)command);
}
#ifdef AIC7XXX_STRICT_PCI_SETUP
command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
#else
command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
#endif
command &= ~PCI_COMMAND_INVALIDATE;
if (aic7xxx_pci_parity == 0)
command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
pci_write_config_word(pdev, PCI_COMMAND, command);
#ifdef AIC7XXX_STRICT_PCI_SETUP
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
if (aic7xxx_verbose & VERBOSE_PROBE2)
{
printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
}
devconfig |= 0x80000040;
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
#endif /* AIC7XXX_STRICT_PCI_SETUP */
#else /* LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
temp_p->pci_bus = pci_bus;
temp_p->pci_device_fn = pci_devfn;
pcibios_read_config_byte(pci_bus, pci_devfn, PCI_INTERRUPT_LINE,
&pci_irq);
temp_p->irq = pci_irq;
pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0,
&piobase);
temp_p->base = piobase;
pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_1,
&mmapbase);
temp_p->mbase = mmapbase;
temp_p->base &= PCI_BASE_ADDRESS_IO_MASK;
temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
current_p = list_p;
while(current_p)
{
if ( ((current_p->pci_bus == temp_p->pci_bus) &&
(current_p->pci_device_fn == temp_p->pci_device_fn)) ||
(temp_p->base && (current_p->base == temp_p->base)) ||
(temp_p->mbase && (current_p->mbase == temp_p->mbase)) )
{
/* duplicate PCI entry, skip it */
kfree(temp_p);
temp_p = NULL;
}
current_p = current_p->next;
}
if ( temp_p == NULL )
continue;
if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command);
if (aic7xxx_verbose & VERBOSE_PROBE2)
{
printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
(int)command);
}
#ifdef AIC7XXX_STRICT_PCI_SETUP
command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
#else
command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
#endif
command &= ~PCI_COMMAND_INVALIDATE;
if (aic7xxx_pci_parity == 0)
command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, command);
#ifdef AIC7XXX_STRICT_PCI_SETUP
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, &devconfig);
if (aic7xxx_verbose & VERBOSE_PROBE2)
{
printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
}
devconfig |= 0x80000040;
pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, devconfig);
#endif /* AIC7XXX_STRICT_PCI_SETUP */
#endif /* LINUIX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
if(temp_p->base && check_region(temp_p->base, MAXREG - MINREG))
{
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: I/O ports already in use, ignoring.\n");
kfree(temp_p);
temp_p = NULL;
continue;
}
temp_p->unpause = INTEN;
temp_p->pause = temp_p->unpause | PAUSE;
if ( ((temp_p->base == 0) &&
(temp_p->mbase == 0)) ||
(temp_p->irq == 0) )
{
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
kfree(temp_p);
temp_p = NULL;
continue;
}
#ifdef MMAPIO
if ( !(temp_p->base) || !(temp_p->flags & AHC_MULTI_CHANNEL) ||
((temp_p->chip != (AHC_AIC7870 | AHC_PCI)) &&
(temp_p->chip != (AHC_AIC7880 | AHC_PCI))) )
{
unsigned long page_offset, base;
base = temp_p->mbase & PAGE_MASK;
page_offset = temp_p->mbase - base;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
temp_p->maddr = ioremap_nocache(base, page_offset + 256);
#else
temp_p->maddr = vremap(base, page_offset + 256);
#endif
if(temp_p->maddr)
{
temp_p->maddr += page_offset;
/*
* We need to check the I/O with the MMAPed address. Some machines
* simply fail to work with MMAPed I/O and certain controllers.
*/
if(aic_inb(temp_p, HCNTRL) == 0xff)
{
/*
* OK.....we failed our test....go back to programmed I/O
*/
printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk(KERN_INFO "aic7xxx: MMAPed I/O failed, reverting to "
"Programmed I/O.\n");
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
iounmap((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
#else
vfree((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
#endif
temp_p->maddr = 0;
if(temp_p->base == 0)
{
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
kfree(temp_p);
temp_p = NULL;
continue;
}
}
}
}
#endif
/*
* Lock out other contenders for our i/o space.
*/
if(temp_p->base)
request_region(temp_p->base, MAXREG - MINREG, "aic7xxx");
/*
* We HAVE to make sure the first pause_sequencer() and all other
* subsequent I/O that isn't PCI config space I/O takes place
* after the MMAPed I/O region is configured and tested. The
* problem is the PowerPC architecture that doesn't support
* programmed I/O at all, so we have to have the MMAP I/O set up
* for this pause to even work on those machines.
*/
pause_sequencer(temp_p);
/*
* Clear out any pending PCI error status messages. Also set
* verbose to 0 so that we don't emit strange PCI error messages
* while cleaning out the current status bits.
*/
oldverbose = aic7xxx_verbose;
aic7xxx_verbose = 0;
aic7xxx_pci_intr(temp_p);
aic7xxx_verbose = oldverbose;
temp_p->bios_address = 0;
/*
* Remember how the card was setup in case there is no seeprom.
*/
if (temp_p->features & AHC_ULTRA2)
temp_p->scsi_id = aic_inb(temp_p, SCSIID_ULTRA2) & OID;
else
temp_p->scsi_id = aic_inb(temp_p, SCSIID) & OID;
/*
* Get current termination setting
*/
sxfrctl1 = aic_inb(temp_p, SXFRCTL1);
if (aic7xxx_chip_reset(temp_p) == -1)
{
release_region(temp_p->base, MAXREG - MINREG);
kfree(temp_p);
temp_p = NULL;
continue;
}
/*
* Very quickly put the term setting back into the register since
* the chip reset may cause odd things to happen. This is to keep
* LVD busses with lots of drives from draining the power out of
* the diffsense line before we get around to running the
* configure_termination() function. Also restore the STPWLEVEL
* bit of DEVCONFIG
*/
aic_outb(temp_p, sxfrctl1, SXFRCTL1);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
pcibios_write_config_dword(temp_p->pci_bus, temp_p->pci_device_fn,
DEVCONFIG, devconfig);
#else
pci_write_config_dword(temp_p->pdev, DEVCONFIG, devconfig);
#endif
sxfrctl1 &= STPWEN;
/*
* We need to set the CHNL? assignments before loading the SEEPROM
* The 3940 and 3985 cards (original stuff, not any of the later
* stuff) are 7870 and 7880 class chips. The Ultra2 stuff falls
* under 7896 and 7897. The 7895 is in a class by itself :)
*/
switch (temp_p->chip & AHC_CHIPID_MASK)
{
case AHC_AIC7870: /* 3840 / 3985 */
case AHC_AIC7880: /* 3840 UW / 3985 UW */
if(temp_p->flags & AHC_MULTI_CHANNEL)
{
switch(PCI_SLOT(temp_p->pci_device_fn))
{
case 5:
temp_p->flags |= AHC_CHNLB;
break;
case 8:
temp_p->flags |= AHC_CHNLB;
break;
case 12:
temp_p->flags |= AHC_CHNLC;
break;
default:
break;
}
}
break;
case AHC_AIC7895: /* 7895 */
case AHC_AIC7896: /* 7896/7 */
case AHC_AIC7899: /* 7899 */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
if (PCI_FUNC(temp_p->pdev->devfn) != 0)
{
temp_p->flags |= AHC_CHNLB;
}
/*
* The 7895 is the only chipset that sets the SCBSIZE32 param
* in the DEVCONFIG register. The Ultra2 chipsets use
* the DSCOMMAND0 register instead.
*/
if ((temp_p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
{
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
devconfig |= SCBSIZE32;
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
}
#else
if (PCI_FUNC(temp_p->pci_device_fn) != 0)
{
temp_p->flags |= AHC_CHNLB;
}
/*
* The 7895 is the only chipset that sets the SCBSIZE32 param
* in the DEVCONFIG register. The Ultra2 chipsets use
* the DSCOMMAND0 register instead.
*/
if ((temp_p->chip & AHC_CHIPID_MASK) == AHC_AIC7895)
{
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
&devconfig);
devconfig |= SCBSIZE32;
pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG,
devconfig);
}
#endif
break;
default:
break;
}
/*
* Loading of the SEEPROM needs to come after we've set the flags
* to indicate possible CHNLB and CHNLC assigments. Otherwise,
* on 394x and 398x cards we'll end up reading the wrong settings
* for channels B and C
*/
switch (temp_p->chip & AHC_CHIPID_MASK)
{
case AHC_AIC7892:
case AHC_AIC7899:
aic_outb(temp_p, 0, SCAMCTL);
/*
* Switch to the alt mode of the chip...
*/
aic_outb(temp_p, aic_inb(temp_p, SFUNCT) | ALT_MODE, SFUNCT);
/*
* Set our options...the last two items set our CRC after x byte
* count in target mode...
*/
aic_outb(temp_p, AUTO_MSGOUT_DE | DIS_MSGIN_DUALEDGE, OPTIONMODE);
aic_outb(temp_p, 0x00, 0x0b);
aic_outb(temp_p, 0x10, 0x0a);
/*
* switch back to normal mode...
*/
aic_outb(temp_p, aic_inb(temp_p, SFUNCT) & ~ALT_MODE, SFUNCT);
aic_outb(temp_p, CRCVALCHKEN | CRCENDCHKEN | CRCREQCHKEN |
TARGCRCENDEN | TARGCRCCNTEN,
CRCCONTROL1);
aic_outb(temp_p, ((aic_inb(temp_p, DSCOMMAND0) | USCBSIZE32 |
MPARCKEN | CIOPARCKEN | CACHETHEN) &
~DPARCKEN), DSCOMMAND0);
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
break;
case AHC_AIC7890:
case AHC_AIC7896:
aic_outb(temp_p, 0, SCAMCTL);
aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
CACHETHEN | MPARCKEN | USCBSIZE32 |
CIOPARCKEN) & ~DPARCKEN, DSCOMMAND0);
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
break;
case AHC_AIC7850:
case AHC_AIC7860:
/*
* Set the DSCOMMAND0 register on these cards different from
* on the 789x cards. Also, read the SEEPROM as well.
*/
aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
CACHETHEN | MPARCKEN) & ~DPARCKEN,
DSCOMMAND0);
/* FALLTHROUGH */
default:
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
break;
case AHC_AIC7880:
/*
* Check the rev of the chipset before we change DSCOMMAND0
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
#else
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
&devconfig);
#endif
if ((devconfig & 0xff) >= 1)
{
aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
CACHETHEN | MPARCKEN) & ~DPARCKEN,
DSCOMMAND0);
}
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
break;
}
/*
* and then we need another switch based on the type in order to
* make sure the channel B primary flag is set properly on 7895
* controllers....Arrrgggghhh!!! We also have to catch the fact
* that when you disable the BIOS on the 7895 on the Intel DK440LX
* motherboard, and possibly others, it only sets the BIOS disabled
* bit on the A channel...I think I'm starting to lean towards
* going postal....
*/
switch(temp_p->chip & AHC_CHIPID_MASK)
{
case AHC_AIC7895:
case AHC_AIC7896:
case AHC_AIC7899:
current_p = list_p;
while(current_p != NULL)
{
if ( (current_p->pci_bus == temp_p->pci_bus) &&
(PCI_SLOT(current_p->pci_device_fn) ==
PCI_SLOT(temp_p->pci_device_fn)) )
{
if ( PCI_FUNC(current_p->pci_device_fn) == 0 )
{
temp_p->flags |=
(current_p->flags & AHC_CHANNEL_B_PRIMARY);
temp_p->flags &= ~(AHC_BIOS_ENABLED|AHC_USEDEFAULTS);
temp_p->flags |=
(current_p->flags & (AHC_BIOS_ENABLED|AHC_USEDEFAULTS));
}
else
{
current_p->flags |=
(temp_p->flags & AHC_CHANNEL_B_PRIMARY);
current_p->flags &= ~(AHC_BIOS_ENABLED|AHC_USEDEFAULTS);
current_p->flags |=
(temp_p->flags & (AHC_BIOS_ENABLED|AHC_USEDEFAULTS));
}
}
current_p = current_p->next;
}
break;
default:
break;
}
/*
* We only support external SCB RAM on the 7895/6/7 chipsets.
* We could support it on the 7890/1 easy enough, but I don't
* know of any 7890/1 based cards that have it. I do know
* of 7895/6/7 cards that have it and they work properly.
*/
switch(temp_p->chip & AHC_CHIPID_MASK)
{
default:
break;
case AHC_AIC7895:
case AHC_AIC7896:
case AHC_AIC7899:
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
#else
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
&devconfig);
#endif
if (temp_p->features & AHC_ULTRA2)
{
if ( (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2) &&
(aic7xxx_scbram) )
{
aic_outb(temp_p,
aic_inb(temp_p, DSCOMMAND0) & ~SCBRAMSEL_ULTRA2,
DSCOMMAND0);
temp_p->flags |= AHC_EXTERNAL_SRAM;
devconfig |= EXTSCBPEN;
}
else if (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2)
{
printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: external SCB RAM detected, "
"but not enabled\n");
}
}
else
{
if ((devconfig & RAMPSM) && (aic7xxx_scbram))
{
devconfig &= ~SCBRAMSEL;
devconfig |= EXTSCBPEN;
temp_p->flags |= AHC_EXTERNAL_SRAM;
}
else if (devconfig & RAMPSM)
{
printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: external SCB RAM detected, "
"but not enabled\n");
}
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
#else
pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG,
devconfig);
#endif
if ( (temp_p->flags & AHC_EXTERNAL_SRAM) &&
(temp_p->flags & AHC_CHNLB) )
aic_outb(temp_p, 1, CCSCBBADDR);
break;
}
/*
* Take the LED out of diagnostic mode
*/
aic_outb(temp_p,
(aic_inb(temp_p, SBLKCTL) & ~(DIAGLEDEN | DIAGLEDON)),
SBLKCTL);
/*
* We don't know where this is set in the SEEPROM or by the
* BIOS, so we default to 100%. On Ultra2 controllers, use 75%
* instead.
*/
if (temp_p->features & AHC_ULTRA2)
{
aic_outb(temp_p, RD_DFTHRSH_MAX | WR_DFTHRSH_MAX, DFF_THRSH);
}
else
{
aic_outb(temp_p, DFTHRSH_100, DSPCISTATUS);
}
/*
* Call our function to fixup any bugs that exist on this chipset.
* This may muck with PCI settings and other device settings, so
* make sure it's after all the other PCI and device register
* tweaks so it can back out bad settings on specific broken cards.
*/
aic7xxx_configure_bugs(temp_p);
if ( list_p == NULL )
{
list_p = current_p = temp_p;
}
else
{
current_p = list_p;
while(current_p->next != NULL)
current_p = current_p->next;
current_p->next = temp_p;
}
temp_p->next = NULL;
found++;
} /* Found an Adaptec PCI device. */
else /* Well, we found one, but we couldn't get any memory */
{
printk("aic7xxx: Found <%s>\n",
board_names[aic_pdevs[i].board_name_index]);
printk(KERN_INFO "aic7xxx: Unable to allocate device memory, "
"skipping.\n");
}
} /* while(pdev=....) */
} /* for PCI_DEVICES */
} /* PCI BIOS present */
#endif CONFIG_PCI
#if defined(__i386__) || defined(__alpha__)
/*
* EISA/VL-bus card signature probe.
*/
slot = MINSLOT;
while ( (slot <= MAXSLOT) &&
!(aic7xxx_no_probe) )
{
base = SLOTBASE(slot) + MINREG;
if (check_region(base, MAXREG - MINREG))
{
/*
* Some other driver has staked a
* claim to this i/o region already.
*/
slot++;
continue; /* back to the beginning of the for loop */
}
flags = 0;
type = aic7xxx_probe(slot, base + AHC_HID0, &flags);
if (type == -1)
{
slot++;
continue;
}
temp_p = kmalloc(sizeof(struct aic7xxx_host), GFP_ATOMIC);
if (temp_p == NULL)
{
printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n");
slot++;
continue; /* back to the beginning of the while loop */
}
/*
* Lock out other contenders for our i/o space.
*/
request_region(base, MAXREG - MINREG, "aic7xxx");
/*
* Pause the card preserving the IRQ type. Allow the operator
* to override the IRQ trigger.
*/
if (aic7xxx_irq_trigger == 1)
hcntrl = IRQMS; /* Level */
else if (aic7xxx_irq_trigger == 0)
hcntrl = 0; /* Edge */
else
hcntrl = inb(base + HCNTRL) & IRQMS; /* Default */
memset(temp_p, 0, sizeof(struct aic7xxx_host));
temp_p->unpause = hcntrl | INTEN;
temp_p->pause = hcntrl | PAUSE | INTEN;
temp_p->base = base;
temp_p->mbase = 0;
temp_p->maddr = 0;
temp_p->pci_bus = 0;
temp_p->pci_device_fn = slot;
aic_outb(temp_p, hcntrl | PAUSE, HCNTRL);
while( (aic_inb(temp_p, HCNTRL) & PAUSE) == 0 ) ;
if (aic7xxx_chip_reset(temp_p) == -1)
temp_p->irq = 0;
else
temp_p->irq = aic_inb(temp_p, INTDEF) & 0x0F;
temp_p->flags |= AHC_PAGESCBS;
switch (temp_p->irq)
{
case 9:
case 10:
case 11:
case 12:
case 14:
case 15:
break;
default:
printk(KERN_WARNING "aic7xxx: Host adapter uses unsupported IRQ "
"level %d, ignoring.\n", temp_p->irq);
kfree(temp_p);
release_region(base, MAXREG - MINREG);
slot++;
continue; /* back to the beginning of the while loop */
}
/*
* We are commited now, everything has been checked and this card
* has been found, now we just set it up
*/
/*
* Insert our new struct into the list at the end
*/
if (list_p == NULL)
{
list_p = current_p = temp_p;
}
else
{
current_p = list_p;
while (current_p->next != NULL)
current_p = current_p->next;
current_p->next = temp_p;
}
switch (type)
{
case 0:
temp_p->board_name_index = 2;
if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at EISA %d\n",
board_names[2], slot);
/* FALLTHROUGH */
case 1:
{
temp_p->chip = AHC_AIC7770 | AHC_EISA;
temp_p->features |= AHC_AIC7770_FE;
temp_p->bios_control = aic_inb(temp_p, HA_274_BIOSCTRL);
/*
* Get the primary channel information. Right now we don't
* do anything with this, but someday we will be able to inform
* the mid-level SCSI code which channel is primary.
*/
if (temp_p->board_name_index == 0)
{
temp_p->board_name_index = 3;
if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at EISA %d\n",
board_names[3], slot);
}
if (temp_p->bios_control & CHANNEL_B_PRIMARY)
{
temp_p->flags |= AHC_CHANNEL_B_PRIMARY;
}
if ((temp_p->bios_control & BIOSMODE) == BIOSDISABLED)
{
temp_p->flags &= ~AHC_BIOS_ENABLED;
}
else
{
temp_p->flags &= ~AHC_USEDEFAULTS;
temp_p->flags |= AHC_BIOS_ENABLED;
if ( (temp_p->bios_control & 0x20) == 0 )
{
temp_p->bios_address = 0xcc000;
temp_p->bios_address += (0x4000 * (temp_p->bios_control & 0x07));
}
else
{
temp_p->bios_address = 0xd0000;
temp_p->bios_address += (0x8000 * (temp_p->bios_control & 0x06));
}
}
temp_p->adapter_control = aic_inb(temp_p, SCSICONF) << 8;
temp_p->adapter_control |= aic_inb(temp_p, SCSICONF + 1);
if (temp_p->features & AHC_WIDE)
{
temp_p->scsi_id = temp_p->adapter_control & HWSCSIID;
temp_p->scsi_id_b = temp_p->scsi_id;
}
else
{
temp_p->scsi_id = (temp_p->adapter_control >> 8) & HSCSIID;
temp_p->scsi_id_b = temp_p->adapter_control & HSCSIID;
}
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
break;
}
case 2:
case 3:
temp_p->chip = AHC_AIC7770 | AHC_VL;
temp_p->features |= AHC_AIC7770_FE;
if (type == 2)
temp_p->flags |= AHC_BIOS_ENABLED;
else
temp_p->flags &= ~AHC_BIOS_ENABLED;
if (aic_inb(temp_p, SCSICONF) & TERM_ENB)
sxfrctl1 = STPWEN;
aic7xxx_load_seeprom(temp_p, &sxfrctl1);
temp_p->board_name_index = 4;
if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at VLB %d\n",
board_names[2], slot);
switch( aic_inb(temp_p, STATUS_2840) & BIOS_SEL )
{
case 0x00:
temp_p->bios_address = 0xe0000;
break;
case 0x20:
temp_p->bios_address = 0xc8000;
break;
case 0x40:
temp_p->bios_address = 0xd0000;
break;
case 0x60:
temp_p->bios_address = 0xd8000;
break;
default:
break; /* can't get here */
}
break;
default: /* Won't get here. */
break;
}
if (aic7xxx_verbose & VERBOSE_PROBE2)
{
printk(KERN_INFO "aic7xxx: BIOS %sabled, IO Port 0x%lx, IRQ %d (%s)\n",
(temp_p->flags & AHC_USEDEFAULTS) ? "dis" : "en", temp_p->base,
temp_p->irq,
(temp_p->pause & IRQMS) ? "level sensitive" : "edge triggered");
printk(KERN_INFO "aic7xxx: Extended translation %sabled.\n",
(temp_p->flags & AHC_EXTEND_TRANS_A) ? "en" : "dis");
}
/*
* All the 7770 based chipsets have this bug
*/
temp_p->bugs |= AHC_BUG_TMODE_WIDEODD;
/*
* Set the FIFO threshold and the bus off time.
*/
hostconf = aic_inb(temp_p, HOSTCONF);
aic_outb(temp_p, hostconf & DFTHRSH, BUSSPD);
aic_outb(temp_p, (hostconf << 2) & BOFF, BUSTIME);
slot++;
found++;
}
#endif /* defined(__i386__) || defined(__alpha__) */
/*
* Now, we re-order the probed devices by BIOS address and BUS class.
* In general, we follow this algorithm to make the adapters show up
* in the same order under linux that the computer finds them.
* 1: All VLB/EISA cards with BIOS_ENABLED first, according to BIOS
* address, going from lowest to highest.
* 2: All PCI controllers with BIOS_ENABLED next, according to BIOS
* address, going from lowest to highest.
* 3: Remaining VLB/EISA controllers going in slot order.
* 4: Remaining PCI controllers, going in PCI device order (reversable)
*/
{
struct aic7xxx_host *sort_list[4] = { NULL, NULL, NULL, NULL };
struct aic7xxx_host *vlb, *pci;
struct aic7xxx_host *prev_p;
struct aic7xxx_host *p;
unsigned char left;
prev_p = vlb = pci = NULL;
temp_p = list_p;
while (temp_p != NULL)
{
switch(temp_p->chip & ~AHC_CHIPID_MASK)
{
case AHC_EISA:
case AHC_VL:
{
p = temp_p;
if (p->flags & AHC_BIOS_ENABLED)
vlb = sort_list[0];
else
vlb = sort_list[2];
if (vlb == NULL)
{
vlb = temp_p;
temp_p = temp_p->next;
vlb->next = NULL;
}
else
{
current_p = vlb;
prev_p = NULL;
while ( (current_p != NULL) &&
(current_p->bios_address < temp_p->bios_address))
{
prev_p = current_p;
current_p = current_p->next;
}
if (prev_p != NULL)
{
prev_p->next = temp_p;
temp_p = temp_p->next;
prev_p->next->next = current_p;
}
else
{
vlb = temp_p;
temp_p = temp_p->next;
vlb->next = current_p;
}
}
if (p->flags & AHC_BIOS_ENABLED)
sort_list[0] = vlb;
else
sort_list[2] = vlb;
break;
}
default: /* All PCI controllers fall through to default */
{
p = temp_p;
if (p->flags & AHC_BIOS_ENABLED)
pci = sort_list[1];
else
pci = sort_list[3];
if (pci == NULL)
{
pci = temp_p;
temp_p = temp_p->next;
pci->next = NULL;
}
else
{
current_p = pci;
prev_p = NULL;
if (!aic7xxx_reverse_scan)
{
while ( (current_p != NULL) &&
( (PCI_SLOT(current_p->pci_device_fn) |
(current_p->pci_bus << 8)) <
(PCI_SLOT(temp_p->pci_device_fn) |
(temp_p->pci_bus << 8)) ) )
{
prev_p = current_p;
current_p = current_p->next;
}
}
else
{
while ( (current_p != NULL) &&
( (PCI_SLOT(current_p->pci_device_fn) |
(current_p->pci_bus << 8)) >
(PCI_SLOT(temp_p->pci_device_fn) |
(temp_p->pci_bus << 8)) ) )
{
prev_p = current_p;
current_p = current_p->next;
}
}
/*
* Are we dealing with a 7895/6/7/9 where we need to sort the
* channels as well, if so, the bios_address values should
* be the same
*/
if ( (current_p) && (temp_p->flags & AHC_MULTI_CHANNEL) &&
(temp_p->pci_bus == current_p->pci_bus) &&
(PCI_SLOT(temp_p->pci_device_fn) ==
PCI_SLOT(current_p->pci_device_fn)) )
{
if (temp_p->flags & AHC_CHNLB)
{
if ( !(temp_p->flags & AHC_CHANNEL_B_PRIMARY) )
{
prev_p = current_p;
current_p = current_p->next;
}
}
else
{
if (temp_p->flags & AHC_CHANNEL_B_PRIMARY)
{
prev_p = current_p;
current_p = current_p->next;
}
}
}
if (prev_p != NULL)
{
prev_p->next = temp_p;
temp_p = temp_p->next;
prev_p->next->next = current_p;
}
else
{
pci = temp_p;
temp_p = temp_p->next;
pci->next = current_p;
}
}
if (p->flags & AHC_BIOS_ENABLED)
sort_list[1] = pci;
else
sort_list[3] = pci;
break;
}
} /* End of switch(temp_p->type) */
} /* End of while (temp_p != NULL) */
/*
* At this point, the cards have been broken into 4 sorted lists, now
* we run through the lists in order and register each controller
*/
{
int i;
left = found;
for (i=0; i<NUMBER(sort_list); i++)
{
temp_p = sort_list[i];
while(temp_p != NULL)
{
template->name = board_names[temp_p->board_name_index];
p = aic7xxx_alloc(template, temp_p);
if (p != NULL)
{
p->instance = found - left;
if (aic7xxx_register(template, p, (--left)) == 0)
{
found--;
aic7xxx_release(p->host);
scsi_unregister(p->host);
}
else if (aic7xxx_dump_card)
{
pause_sequencer(p);
aic7xxx_print_card(p);
aic7xxx_print_scratch_ram(p);
unpause_sequencer(p, TRUE);
}
}
current_p = temp_p;
temp_p = (struct aic7xxx_host *)temp_p->next;
kfree(current_p);
}
}
}
}
return (found);
}
Generated by GNU enscript 1.6.4.