summaryrefslogtreecommitdiffstats
path: root/nic3com.c
diff options
context:
space:
mode:
Diffstat (limited to 'nic3com.c')
-rw-r--r--nic3com.c111
1 files changed, 66 insertions, 45 deletions
diff --git a/nic3com.c b/nic3com.c
index b7b967a44..a578d4853 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -14,12 +14,11 @@
* GNU General Public License for more details.
*/
-#if defined(__i386__) || defined(__x86_64__)
-
#include <stdlib.h>
#include "flash.h"
#include "programmer.h"
-#include "hwaccess.h"
+#include "hwaccess_x86_io.h"
+#include "platform/pci.h"
#define BIOS_ROM_ADDR 0x04
#define BIOS_ROM_DATA 0x08
@@ -29,17 +28,19 @@
#define PCI_VENDOR_ID_3COM 0x10b7
-static uint32_t io_base_addr = 0;
-static uint32_t internal_conf;
-static uint16_t id;
+struct nic3com_data {
+ uint32_t io_base_addr;
+ uint32_t internal_conf;
+ uint16_t id;
+};
-const struct dev_entry nics_3com[] = {
+static const struct dev_entry nics_3com[] = {
/* 3C90xB */
{0x10b7, 0x9055, OK, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-TX"},
{0x10b7, 0x9001, NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-T4" },
{0x10b7, 0x9004, OK, "3COM", "3C90xB: PCI 10BASE-T (TPO)" },
{0x10b7, 0x9005, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2/AUI (COMBO)" },
- {0x10b7, 0x9006, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2 (TPC)" },
+ {0x10b7, 0x9006, OK, "3COM", "3C90xB: PCI 10BASE-T/10BASE2 (TPC)" },
{0x10b7, 0x900a, NT, "3COM", "3C90xB: PCI 10BASE-FL" },
{0x10b7, 0x905a, NT, "3COM", "3C90xB: PCI 10BASE-FX" },
{0x10b7, 0x9058, OK, "3COM", "3C905B: Cyclone 10/100/BNC" },
@@ -54,41 +55,57 @@ const struct dev_entry nics_3com[] = {
};
static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
- chipaddr addr);
+ chipaddr addr)
+{
+ struct nic3com_data *data = flash->mst->par.data;
+
+ OUTL((uint32_t)addr, data->io_base_addr + BIOS_ROM_ADDR);
+ OUTB(val, data->io_base_addr + BIOS_ROM_DATA);
+}
+
static uint8_t nic3com_chip_readb(const struct flashctx *flash,
- const chipaddr addr);
-static const struct par_master par_master_nic3com = {
- .chip_readb = nic3com_chip_readb,
- .chip_readw = fallback_chip_readw,
- .chip_readl = fallback_chip_readl,
- .chip_readn = fallback_chip_readn,
- .chip_writeb = nic3com_chip_writeb,
- .chip_writew = fallback_chip_writew,
- .chip_writel = fallback_chip_writel,
- .chip_writen = fallback_chip_writen,
-};
+ const chipaddr addr)
+{
+ struct nic3com_data *data = flash->mst->par.data;
+
+ OUTL((uint32_t)addr, data->io_base_addr + BIOS_ROM_ADDR);
+ return INB(data->io_base_addr + BIOS_ROM_DATA);
+}
-static int nic3com_shutdown(void *data)
+static int nic3com_shutdown(void *par_data)
{
+ struct nic3com_data *data = par_data;
+ const uint16_t id = data->id;
+
/* 3COM 3C90xB cards need a special fixup. */
if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
|| id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) {
/* 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);
+ OUTW(SELECT_REG_WINDOW + 3, data->io_base_addr + INT_STATUS);
+ OUTL(data->internal_conf, data->io_base_addr + INTERNAL_CONFIG);
}
+ free(data);
return 0;
}
-int nic3com_init(void)
+static const struct par_master par_master_nic3com = {
+ .chip_readb = nic3com_chip_readb,
+ .chip_writeb = nic3com_chip_writeb,
+ .shutdown = nic3com_shutdown,
+};
+
+static int nic3com_init(const struct programmer_cfg *cfg)
{
struct pci_dev *dev = NULL;
+ uint32_t io_base_addr = 0;
+ uint32_t internal_conf = 0;
+ uint16_t id;
if (rget_io_perms())
return 1;
- dev = pcidev_init(nics_3com, PCI_BASE_ADDRESS_0);
+ dev = pcidev_init(cfg, nics_3com, PCI_BASE_ADDRESS_0);
if (!dev)
return 1;
@@ -116,29 +133,33 @@ int nic3com_init(void)
*/
OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
- if (register_shutdown(nic3com_shutdown, NULL))
- return 1;
+ struct nic3com_data *data = calloc(1, sizeof(*data));
+ if (!data) {
+ msg_perr("Unable to allocate space for PAR master data\n");
+ goto init_err_cleanup_exit;
+ }
+ data->io_base_addr = io_base_addr;
+ data->internal_conf = internal_conf;
+ data->id = id;
max_rom_decode.parallel = 128 * 1024;
- register_par_master(&par_master_nic3com, BUS_PARALLEL);
- return 0;
-}
-
-static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
- chipaddr addr)
-{
- OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
- OUTB(val, io_base_addr + BIOS_ROM_DATA);
-}
+ return register_par_master(&par_master_nic3com, BUS_PARALLEL, data);
-static uint8_t nic3com_chip_readb(const struct flashctx *flash,
- const chipaddr addr)
-{
- OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
- return INB(io_base_addr + BIOS_ROM_DATA);
+init_err_cleanup_exit:
+ /* 3COM 3C90xB cards need a special fixup. */
+ if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
+ || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) {
+ /* 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);
+ }
+ return 1;
}
-#else
-#error PCI port I/O access is not supported on this architecture yet.
-#endif
+const struct programmer_entry programmer_nic3com = {
+ .name = "nic3com",
+ .type = PCI,
+ .devs.dev = nics_3com,
+ .init = nic3com_init,
+};