static inline void bt3c_write(struct bt3c_softc *sc, uint16_t addr, uint16_t data) { bt3c_set_address(sc, addr); bt3c_put(sc, data); }
static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) { int actual = 0; bt3c_address(iobase, 0x7080); /* Fill FIFO with current frame */ while (actual < len) { /* Transmit next byte */ bt3c_put(iobase, buf[actual]); actual++; } bt3c_io_write(iobase, 0x7005, actual); return actual; }
inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value) { bt3c_address(iobase, addr); bt3c_put(iobase, value); }
static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count) { char *ptr = (char *) firmware; char b[9]; unsigned int iobase, size, addr, fcs, tmp; int i, err = 0; iobase = info->link.io.BasePort1; /* Reset */ bt3c_io_write(iobase, 0x8040, 0x0404); bt3c_io_write(iobase, 0x8040, 0x0400); udelay(1); bt3c_io_write(iobase, 0x8040, 0x0404); udelay(17); /* Load */ while (count) { if (ptr[0] != 'S') { BT_ERR("Bad address in firmware"); err = -EFAULT; goto error; } memset(b, 0, sizeof(b)); memcpy(b, ptr + 2, 2); size = simple_strtol(b, NULL, 16); memset(b, 0, sizeof(b)); memcpy(b, ptr + 4, 8); addr = simple_strtol(b, NULL, 16); memset(b, 0, sizeof(b)); memcpy(b, ptr + (size * 2) + 2, 2); fcs = simple_strtol(b, NULL, 16); memset(b, 0, sizeof(b)); for (tmp = 0, i = 0; i < size; i++) { memcpy(b, ptr + (i * 2) + 2, 2); tmp += simple_strtol(b, NULL, 16); } if (((tmp + fcs) & 0xff) != 0xff) { BT_ERR("Checksum error in firmware"); err = -EILSEQ; goto error; } if (ptr[1] == '3') { bt3c_address(iobase, addr); memset(b, 0, sizeof(b)); for (i = 0; i < (size - 4) / 2; i++) { memcpy(b, ptr + (i * 4) + 12, 4); tmp = simple_strtol(b, NULL, 16); bt3c_put(iobase, tmp); } } ptr += (size * 2) + 6; count -= (size * 2) + 6; } udelay(17); /* Boot */ bt3c_address(iobase, 0x3000); outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL); error: udelay(17); /* Clear */ bt3c_io_write(iobase, 0x7006, 0x0000); bt3c_io_write(iobase, 0x7005, 0x0000); bt3c_io_write(iobase, 0x7001, 0x0000); return err; }