Support for IDE controllers that announce themselves as RAID controllers.

This commit is contained in:
Philip Homburg 2006-04-04 12:27:28 +00:00
parent acf9910a6e
commit 36f4976e17

View File

@ -324,6 +324,17 @@ PRIVATE phys_bytes prdt_phys;
#define PRDTE_FL_EOT 0x80 /* End of table */ #define PRDTE_FL_EOT 0x80 /* End of table */
/* Some IDE devices announce themselves as RAID controllers */
PRIVATE struct
{
u16_t vendor;
u16_t device;
} raid_table[]=
{
{ 0x1106, 0x3149 }, /* VIA VT6420 */
{ 0, 0 } /* end of list */
};
FORWARD _PROTOTYPE( void init_params, (void) ); FORWARD _PROTOTYPE( void init_params, (void) );
FORWARD _PROTOTYPE( void init_drive, (struct wini *w, int base_cmd, FORWARD _PROTOTYPE( void init_drive, (struct wini *w, int base_cmd,
int base_ctl, int base_dma, int irq, int ack, int hook, int base_ctl, int base_dma, int irq, int ack, int hook,
@ -511,31 +522,58 @@ PRIVATE void init_drive(struct wini *w, int base_cmd, int base_ctl,
PRIVATE void init_params_pci(int skip) PRIVATE void init_params_pci(int skip)
{ {
int i, r, devind, drive; int i, r, devind, drive;
int irq, irq_hook, raid;
u8_t bcr, scr, interface;
u16_t vid, did; u16_t vid, did;
u32_t base_dma; u32_t base_dma, t3;
pci_init(); pci_init();
for(drive = w_next_drive; drive < MAX_DRIVES; drive++) for(drive = w_next_drive; drive < MAX_DRIVES; drive++)
wini[drive].state = IGNORING; wini[drive].state = IGNORING;
for(r = pci_first_dev(&devind, &vid, &did); r != 0; for(r = pci_first_dev(&devind, &vid, &did); r != 0;
r = pci_next_dev(&devind, &vid, &did)) { r = pci_next_dev(&devind, &vid, &did)) {
int interface, irq, irq_hook;
/* Base class must be 01h (mass storage), subclass must raid= 0;
* be 01h (ATA).
/* Except class 01h (mass storage), subclass be 01h (ATA).
* Also check listed RAID controllers.
*/ */
if (pci_attr_r8(devind, PCI_BCR) != 0x01 || bcr= pci_attr_r8(devind, PCI_BCR);
pci_attr_r8(devind, PCI_SCR) != 0x01) { scr= pci_attr_r8(devind, PCI_SCR);
continue; interface= pci_attr_r8(devind, PCI_PIFR);
} t3= ((bcr << 16) | (scr << 8) | interface);
if (bcr == PCI_BCR_MASS_STORAGE && scr == PCI_MS_IDE)
; /* Okay */
else if (t3 == PCI_T3_RAID)
{
for (i= 0; raid_table[i].vendor != 0; i++)
{
if (raid_table[i].vendor == vid &&
raid_table[i].device == did)
{
break;
}
}
if (raid_table[i].vendor == 0)
{
printf(
"atapci skipping unsupported RAID controller 0x%04x / 0x%04x\n",
vid, did);
continue;
}
printf("found supported RAID controller\n");
raid= 1;
}
else
continue; /* Unsupported device class */
/* Found a controller. /* Found a controller.
* Programming interface register tells us more. * Programming interface register tells us more.
*/ */
interface = pci_attr_r8(devind, PCI_PIFR);
irq = pci_attr_r8(devind, PCI_ILR); irq = pci_attr_r8(devind, PCI_ILR);
/* Any non-compat drives? */ /* Any non-compat drives? */
if (interface & (ATA_IF_NOTCOMPAT1 | ATA_IF_NOTCOMPAT2)) { if (raid || (interface & (ATA_IF_NOTCOMPAT1 | ATA_IF_NOTCOMPAT2))) {
int s; int s;
if (w_next_drive >= MAX_DRIVES) if (w_next_drive >= MAX_DRIVES)
@ -548,7 +586,12 @@ PRIVATE void init_params_pci(int skip)
irq_hook = irq; irq_hook = irq;
if (skip > 0) { if (skip > 0) {
if (w_pci_debug) printf("atapci skipping controller (remain %d)\n", skip); if (w_pci_debug)
{
printf(
"atapci skipping controller (remain %d)\n",
skip);
}
skip--; skip--;
continue; continue;
} }
@ -565,7 +608,7 @@ PRIVATE void init_params_pci(int skip)
base_dma = pci_attr_r32(devind, PCI_BAR_5) & 0xfffffffc; base_dma = pci_attr_r32(devind, PCI_BAR_5) & 0xfffffffc;
/* Primary channel not in compatability mode? */ /* Primary channel not in compatability mode? */
if (interface & ATA_IF_NOTCOMPAT1) { if (raid || (interface & ATA_IF_NOTCOMPAT1)) {
u32_t base_cmd, base_ctl; u32_t base_cmd, base_ctl;
base_cmd = pci_attr_r32(devind, PCI_BAR) & 0xfffffffc; base_cmd = pci_attr_r32(devind, PCI_BAR) & 0xfffffffc;
@ -593,7 +636,7 @@ PRIVATE void init_params_pci(int skip)
} }
/* Secondary channel not in compatability mode? */ /* Secondary channel not in compatability mode? */
if (interface & ATA_IF_NOTCOMPAT2) { if (raid || (interface & ATA_IF_NOTCOMPAT2)) {
u32_t base_cmd, base_ctl; u32_t base_cmd, base_ctl;
base_cmd = pci_attr_r32(devind, PCI_BAR_3) & 0xfffffffc; base_cmd = pci_attr_r32(devind, PCI_BAR_3) & 0xfffffffc;