diff options
-rw-r--r-- | flash.h | 3 | ||||
-rw-r--r-- | flashchips.c | 14 | ||||
-rw-r--r-- | nic3com.c | 26 | ||||
-rw-r--r-- | pcidev.c | 10 |
4 files changed, 49 insertions, 4 deletions
@@ -193,6 +193,7 @@ struct flashchip { #define TEST_OK_ERASE (1<<2) #define TEST_OK_WRITE (1<<3) #define TEST_OK_PR (TEST_OK_PROBE|TEST_OK_READ) +#define TEST_OK_PRE (TEST_OK_PROBE|TEST_OK_READ|TEST_OK_ERASE) #define TEST_OK_PREW (TEST_OK_PROBE|TEST_OK_READ|TEST_OK_ERASE|TEST_OK_WRITE) #define TEST_OK_MASK 0x0f @@ -258,6 +259,7 @@ extern struct flashchip flashchips[]; #define AT_26DF321 0x4700 /* also 25DF321 */ #define AT_26F004 0x0400 #define AT_29C040A 0xA4 +#define AT_29C010A 0xD5 #define AT_29C020 0xDA #define AT_45BR3214B /* No ID available */ #define AT_45CS1282 0x2920 @@ -559,6 +561,7 @@ struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device, extern uint32_t io_base_addr; extern struct pci_access *pacc; extern struct pci_filter filter; +extern struct pci_dev *pcidev_dev; struct pcidev_status { uint16_t vendor_id; uint16_t device_id; diff --git a/flashchips.c b/flashchips.c index eb241a90..36307c1a 100644 --- a/flashchips.c +++ b/flashchips.c @@ -376,6 +376,20 @@ struct flashchip flashchips[] = { { .vendor = "Atmel", + .name = "AT29C010A", + .manufacture_id = ATMEL_ID, + .model_id = AT_29C010A, + .total_size = 128, + .page_size = 128, + .tested = TEST_OK_PRE, + .probe = probe_jedec, + .erase = erase_chip_jedec, + .write = write_jedec, /* FIXME */ + .read = read_memmapped, + }, + + { + .vendor = "Atmel", .name = "AT29C020", .manufacture_id = ATMEL_ID, .model_id = AT_29C020, @@ -29,13 +29,17 @@ #define BIOS_ROM_ADDR 0x04 #define BIOS_ROM_DATA 0x08 #define INT_STATUS 0x0e +#define INTERNAL_CONFIG 0x00 #define SELECT_REG_WINDOW 0x800 #define PCI_VENDOR_ID_3COM 0x10b7 +uint32_t internal_conf; +uint16_t id; + struct pcidev_status nics_3com[] = { /* 3C90xB */ - {0x10b7, 0x9055, PCI_NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-TX"}, + {0x10b7, 0x9055, PCI_OK, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-TX"}, {0x10b7, 0x9001, PCI_NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-T4" }, {0x10b7, 0x9004, PCI_NT, "3COM", "3C90xB: PCI 10BASE-T (TPO)" }, {0x10b7, 0x9005, PCI_NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2/AUI (COMBO)" }, @@ -57,6 +61,18 @@ int nic3com_init(void) get_io_perms(); io_base_addr = pcidev_init(PCI_VENDOR_ID_3COM, nics_3com); + id = pcidev_dev->device_id; + + /* 3COM 3C90xB cards need a special fixup. */ + if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005 + || id == 0x9006 || id == 0x900a || id == 0x905a) { + /* Select register window 3 and save the receiver status. */ + OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS); + internal_conf = INL(io_base_addr + INTERNAL_CONFIG); + + /* Set receiver type to MII for full BIOS ROM access. */ + OUTL((internal_conf & 0xf00fffff) | 0x00600000, io_base_addr); + } /* * The lowest 16 bytes of the I/O mapped register space of (most) 3COM @@ -70,6 +86,14 @@ int nic3com_init(void) int nic3com_shutdown(void) { + /* 3COM 3C90xB cards need a special fixup. */ + if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005 + || id == 0x9006 || id == 0x900a || id == 0x905a) { + /* Select register window 3 and restore the receiver status. */ + OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS); + OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG); + } + free(pcidev_bdf); pci_cleanup(pacc); #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -32,6 +32,7 @@ uint32_t io_base_addr; struct pci_access *pacc; struct pci_filter filter; char *pcidev_bdf = NULL; +struct pci_dev *pcidev_dev = NULL; uint32_t pcidev_validate(struct pci_dev *dev, struct pcidev_status *devs) { @@ -67,7 +68,7 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs) struct pci_dev *dev; char *msg = NULL; int found = 0; - uint32_t addr = 0; + uint32_t addr = 0, curaddr = 0; pacc = pci_alloc(); /* Get the pci_access structure */ pci_init(pacc); /* Initialize the PCI library */ @@ -85,8 +86,11 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs) for (dev = pacc->devices; dev; dev = dev->next) { if (pci_filter_match(&filter, dev)) { - if ((addr = pcidev_validate(dev, devs)) != 0) + if ((addr = pcidev_validate(dev, devs)) != 0) { + curaddr = addr; + pcidev_dev = dev; found++; + } } } @@ -102,7 +106,7 @@ uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs) exit(1); } - return addr; + return curaddr; } void print_supported_pcidevs(struct pcidev_status *devs) |