diff options
Diffstat (limited to 'drivers')
29 files changed, 843 insertions, 265 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 7b2ec50..8c785ae 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -37,11 +37,28 @@ #include <linux/ctype.h> #include <ahci.h> +static int ata_io_flush(u8 port); + struct ahci_probe_ent *probe_ent = NULL; hd_driveid_t *ataid[AHCI_MAX_PORTS]; #define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0) +/* + * Some controllers limit number of blocks they can read/write at once. + * Contemporary SSD devices work much faster if the read/write size is aligned + * to a power of 2. Let's set default to 128 and allowing to be overwritten if + * needed. + */ +#ifndef MAX_SATA_BLOCKS_READ_WRITE +#define MAX_SATA_BLOCKS_READ_WRITE 0x80 +#endif + +/* Maximum timeouts for each event */ +#define WAIT_MS_SPINUP 10000 +#define WAIT_MS_DATAIO 5000 +#define WAIT_MS_FLUSH 5000 +#define WAIT_MS_LINKUP 4 static inline u32 ahci_port_base(u32 base, u32 port) { @@ -60,7 +77,39 @@ static void ahci_setup_port(struct ahci_ioports *port, unsigned long base, #define msleep(a) udelay(a * 1000) -#define ssleep(a) msleep(a * 1000) + +static void ahci_dcache_flush_range(unsigned begin, unsigned len) +{ + const unsigned long start = begin; + const unsigned long end = start + len; + + debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end); + flush_dcache_range(start, end); +} + +/* + * SATA controller DMAs to physical RAM. Ensure data from the + * controller is invalidated from dcache; next access comes from + * physical RAM. + */ +static void ahci_dcache_invalidate_range(unsigned begin, unsigned len) +{ + const unsigned long start = begin; + const unsigned long end = start + len; + + debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end); + invalidate_dcache_range(start, end); +} + +/* + * Ensure data for SATA controller is flushed out of dcache and + * written to physical memory. + */ +static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp) +{ + ahci_dcache_flush_range((unsigned long)pp->cmd_slot, + AHCI_PORT_PRIV_DMA_SZ); +} static int waiting_for_cmd_completed(volatile u8 *offset, int timeout_msec, @@ -84,13 +133,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) unsigned short vendor; #endif volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base; - u32 tmp, cap_save; + u32 tmp, cap_save, cmd; int i, j; volatile u8 *port_mmio; + debug("ahci_host_init: start\n"); + cap_save = readl(mmio + HOST_CAP); cap_save &= ((1 << 28) | (1 << 17)); - cap_save |= (1 << 27); + cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */ /* global controller reset */ tmp = readl(mmio + HOST_CTL); @@ -100,13 +151,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) /* reset must complete within 1 second, or * the hardware should be considered fried. */ - ssleep(1); - - tmp = readl(mmio + HOST_CTL); - if (tmp & HOST_RESET) { - debug("controller reset failed (0x%x)\n", tmp); - return -1; - } + i = 1000; + do { + udelay(1000); + tmp = readl(mmio + HOST_CTL); + if (!i--) { + debug("controller reset failed (0x%x)\n", tmp); + return -1; + } + } while (tmp & HOST_RESET); writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL); writel(cap_save, mmio + HOST_CAP); @@ -129,6 +182,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) debug("cap 0x%x port_map 0x%x n_ports %d\n", probe_ent->cap, probe_ent->port_map, probe_ent->n_ports); + if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID) + probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID; + for (i = 0; i < probe_ent->n_ports; i++) { probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i); port_mmio = (u8 *) probe_ent->port[i].port_mmio; @@ -138,6 +194,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) tmp = readl(port_mmio + PORT_CMD); if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | PORT_CMD_FIS_RX | PORT_CMD_START)) { + debug("Port %d is active. Deactivating.\n", i); tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | PORT_CMD_FIS_RX | PORT_CMD_START); writel_with_flush(tmp, port_mmio + PORT_CMD); @@ -148,16 +205,53 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) msleep(500); } - writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD); - + /* Add the spinup command to whatever mode bits may + * already be on in the command register. + */ + cmd = readl(port_mmio + PORT_CMD); + cmd |= PORT_CMD_FIS_RX; + cmd |= PORT_CMD_SPIN_UP; + writel_with_flush(cmd, port_mmio + PORT_CMD); + + /* Bring up SATA link. + * SATA link bringup time is usually less than 1 ms; only very + * rarely has it taken between 1-2 ms. Never seen it above 2 ms. + */ j = 0; - while (j < 100) { - msleep(10); + while (j < WAIT_MS_LINKUP) { tmp = readl(port_mmio + PORT_SCR_STAT); if ((tmp & 0xf) == 0x3) break; + udelay(1000); j++; } + if (j == WAIT_MS_LINKUP) { + printf("SATA link %d timeout.\n", i); + continue; + } else { + debug("SATA link ok.\n"); + } + + /* Clear error status */ + tmp = readl(port_mmio + PORT_SCR_ERR); + if (tmp) + writel(tmp, port_mmio + PORT_SCR_ERR); + + debug("Spinning up device on SATA port %d... ", i); + + j = 0; + while (j < WAIT_MS_SPINUP) { + tmp = readl(port_mmio + PORT_TFDATA); + if (!(tmp & (ATA_STAT_BUSY | ATA_STAT_DRQ))) + break; + udelay(1000); + j++; + } + printf("Target spinup took %d ms.\n", j); + if (j == WAIT_MS_SPINUP) + debug("timeout.\n"); + else + debug("ok.\n"); tmp = readl(port_mmio + PORT_SCR_ERR); debug("PORT_SCR_ERR 0x%x\n", tmp); @@ -174,9 +268,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) /* set irq mask (enables interrupts) */ writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); - /*register linkup ports */ + /* register linkup ports */ tmp = readl(port_mmio + PORT_SCR_STAT); - debug("Port %d status: 0x%x\n", i, tmp); + debug("SATA port %d status: 0x%x\n", i, tmp); if ((tmp & 0xf) == 0x03) probe_ent->link_port_map |= (0x01 << i); } @@ -202,12 +296,13 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) u16 cc; #endif volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base; - u32 vers, cap, impl, speed; + u32 vers, cap, cap2, impl, speed; const char *speed_s; const char *scc_s; vers = readl(mmio + HOST_VERSION); cap = probe_ent->cap; + cap2 = readl(mmio + HOST_CAP2); impl = probe_ent->port_map; speed = (cap >> 20) & 0xf; @@ -215,6 +310,8 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) speed_s = "1.5"; else if (speed == 2) speed_s = "3"; + else if (speed == 3) + speed_s = "6"; else speed_s = "?"; @@ -240,8 +337,9 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s); printf("flags: " - "%s%s%s%s%s%s" - "%s%s%s%s%s%s%s\n", + "%s%s%s%s%s%s%s" + "%s%s%s%s%s%s%s" + "%s%s%s%s%s%s\n", cap & (1 << 31) ? "64bit " : "", cap & (1 << 30) ? "ncq " : "", cap & (1 << 28) ? "ilck " : "", @@ -252,9 +350,16 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) cap & (1 << 19) ? "nz " : "", cap & (1 << 18) ? "only " : "", cap & (1 << 17) ? "pmp " : "", + cap & (1 << 16) ? "fbss " : "", cap & (1 << 15) ? "pio " : "", cap & (1 << 14) ? "slum " : "", - cap & (1 << 13) ? "part " : ""); + cap & (1 << 13) ? "part " : "", + cap & (1 << 7) ? "ccc " : "", + cap & (1 << 6) ? "ems " : "", + cap & (1 << 5) ? "sxs " : "", + cap2 & (1 << 2) ? "apst " : "", + cap2 & (1 << 1) ? "nvmp " : "", + cap2 & (1 << 0) ? "boh " : ""); } #ifndef CONFIG_SCSI_AHCI_PLAT @@ -277,8 +382,8 @@ static int ahci_init_one(pci_dev_t pdev) probe_ent->pio_mask = 0x1f; probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ - probe_ent->mmio_base = (u32)pci_map_bar(pdev, AHCI_PCI_BAR, - PCI_REGION_MEM); + pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &probe_ent->mmio_base); + debug("ahci mmio_base=0x%08x\n", probe_ent->mmio_base); /* Take from kernel: * JMicron-specific fixup: @@ -342,6 +447,7 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts) } +#ifdef CONFIG_AHCI_SETFEATURES_XFER static void ahci_set_feature(u8 port) { struct ahci_ioports *pp = &(probe_ent->port[port]); @@ -349,23 +455,26 @@ static void ahci_set_feature(u8 port) u32 cmd_fis_len = 5; /* five dwords */ u8 fis[20]; - /*set feature */ - memset(fis, 0, 20); + /* set feature */ + memset(fis, 0, sizeof(fis)); fis[0] = 0x27; fis[1] = 1 << 7; fis[2] = ATA_CMD_SETF; fis[3] = SETFEATURES_XFER; fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01; - memcpy((unsigned char *)pp->cmd_tbl, fis, 20); + memcpy((unsigned char *)pp->cmd_tbl, fis, sizeof(fis)); ahci_fill_cmd_slot(pp, cmd_fis_len); + ahci_dcache_flush_sata_cmd(pp); writel(1, port_mmio + PORT_CMD_ISSUE); readl(port_mmio + PORT_CMD_ISSUE); - if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) { - printf("set feature error!\n"); + if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, + WAIT_MS_DATAIO, 0x1)) { + printf("set feature error on port %d!\n", port); } } +#endif static int ahci_port_start(u8 port) @@ -397,25 +506,27 @@ static int ahci_port_start(u8 port) * First item in chunk of DMA memory: 32-slot command table, * 32 bytes each in size */ - pp->cmd_slot = (struct ahci_cmd_hdr *)mem; - debug("cmd_slot = %p\n", pp->cmd_slot); + pp->cmd_slot = + (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem); + debug("cmd_slot = 0x%x\n", (unsigned)pp->cmd_slot); mem += (AHCI_CMD_SLOT_SZ + 224); /* * Second item: Received-FIS area */ - pp->rx_fis = mem; + pp->rx_fis = virt_to_phys((void *)mem); mem += AHCI_RX_FIS_SZ; /* * Third item: data area for storing a single command * and its scatter-gather table */ - pp->cmd_tbl = mem; + pp->cmd_tbl = virt_to_phys((void *)mem); debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl); mem += AHCI_CMD_TBL_HDR; - pp->cmd_tbl_sg = (struct ahci_sg *)mem; + pp->cmd_tbl_sg = + (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem); writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR); @@ -431,8 +542,8 @@ static int ahci_port_start(u8 port) } -static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf, - int buf_len) +static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf, + int buf_len, u8 is_write) { struct ahci_ioports *pp = &(probe_ent->port[port]); @@ -441,10 +552,10 @@ static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf, u32 port_status; int sg_count; - debug("Enter get_ahci_device_data: for port %d\n", port); + debug("Enter %s: for port %d\n", __func__, port); if (port > probe_ent->n_ports) { - printf("Invaild port number %d\n", port); + printf("Invalid port number %d\n", port); return -1; } @@ -457,17 +568,22 @@ static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf, memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len); sg_count = ahci_fill_sg(port, buf, buf_len); - opts = (fis_len >> 2) | (sg_count << 16); + opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6); ahci_fill_cmd_slot(pp, opts); + ahci_dcache_flush_sata_cmd(pp); + ahci_dcache_flush_range((unsigned)buf, (unsigned)buf_len); + writel_with_flush(1, port_mmio + PORT_CMD_ISSUE); - if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) { + if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, + WAIT_MS_DATAIO, 0x1)) { printf("timeout exit!\n"); return -1; } - debug("get_ahci_device_data: %d byte transferred.\n", - pp->cmd_slot->status); + + ahci_dcache_invalidate_range((unsigned)buf, (unsigned)buf_len); + debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status); return 0; } @@ -526,7 +642,7 @@ static int ata_scsiop_inquiry(ccb *pccb) if (pccb->datalen <= 35) return 0; - memset(fis, 0, 20); + memset(fis, 0, sizeof(fis)); /* Construct the FIS */ fis[0] = 0x27; /* Host to device FIS. */ fis[1] = 1 << 7; /* Command FIS. */ @@ -537,8 +653,8 @@ static int ata_scsiop_inquiry(ccb *pccb) if (!(tmpid = malloc(sizeof(hd_driveid_t)))) return -ENOMEM; - if (get_ahci_device_data(port, (u8 *) & fis, 20, - tmpid, sizeof(hd_driveid_t))) { + if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), tmpid, + sizeof(hd_driveid_t), 0)) { debug("scsi_ahci: SCSI inquiry command failure.\n"); return -EIO; } @@ -557,46 +673,91 @@ static int ata_scsiop_inquiry(ccb *pccb) /* - * SCSI READ10 command operation. + * SCSI READ10/WRITE10 command operation. */ -static int ata_scsiop_read10(ccb * pccb) +static int ata_scsiop_read_write(ccb *pccb, u8 is_write) { - u32 len = 0; + u32 lba = 0; + u16 blocks = 0; u8 fis[20]; + u8 *user_buffer = pccb->pdata; + u32 user_buffer_size = pccb->datalen; - len = (((u32) pccb->cmd[7]) << 8) | ((u32) pccb->cmd[8]); + /* Retrieve the base LBA number from the ccb structure. */ + memcpy(&lba, pccb->cmd + 2, sizeof(lba)); + lba = be32_to_cpu(lba); - /* For 10-byte and 16-byte SCSI R/W commands, transfer + /* + * And the number of blocks. + * + * For 10-byte and 16-byte SCSI R/W commands, transfer * length 0 means transfer 0 block of data. * However, for ATA R/W commands, sector count 0 means * 256 or 65536 sectors, not 0 sectors as in SCSI. * * WARNING: one or two older ATA drives treat 0 as 0... */ - if (!len) - return 0; - memset(fis, 0, 20); + blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]); - /* Construct the FIS */ - fis[0] = 0x27; /* Host to device FIS. */ - fis[1] = 1 << 7; /* Command FIS. */ - fis[2] = ATA_CMD_RD_DMA; /* Command byte. */ - - /* LBA address, only support LBA28 in this driver */ - fis[4] = pccb->cmd[5]; - fis[5] = pccb->cmd[4]; - fis[6] = pccb->cmd[3]; - fis[7] = (pccb->cmd[2] & 0x0f) | 0xe0; - - /* Sector Count */ - fis[12] = pccb->cmd[8]; - fis[13] = pccb->cmd[7]; - - /* Read from ahci */ - if (get_ahci_device_data(pccb->target, (u8 *) & fis, 20, - pccb->pdata, pccb->datalen)) { - debug("scsi_ahci: SCSI READ10 command failure.\n"); - return -EIO; + debug("scsi_ahci: %s %d blocks starting from lba 0x%x\n", + is_write ? "write" : "read", (unsigned)lba, blocks); + + /* Preset the FIS */ + memset(fis, 0, sizeof(fis)); + fis[0] = 0x27; /* Host to device FIS. */ + fis[1] = 1 << 7; /* Command FIS. */ + /* Command byte (read/write). */ + fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT; + + while (blocks) { + u16 now_blocks; /* number of blocks per iteration */ + u32 transfer_size; /* number of bytes per iteration */ + + now_blocks = min(MAX_SATA_BLOCKS_READ_WRITE, blocks); + + transfer_size = ATA_BLOCKSIZE * now_blocks; + if (transfer_size > user_buffer_size) { + printf("scsi_ahci: Error: buffer too small.\n"); + return -EIO; + } + + /* LBA48 SATA command but only use 32bit address range within + * that. The next smaller command range (28bit) is too small. + */ + fis[4] = (lba >> 0) & 0xff; + fis[5] = (lba >> 8) & 0xff; + fis[6] = (lba >> 16) & 0xff; + fis[7] = 1 << 6; /* device reg: set LBA mode */ + fis[8] = ((lba >> 24) & 0xff); + fis[3] = 0xe0; /* features */ + + /* Block (sector) count */ + fis[12] = (now_blocks >> 0) & 0xff; + fis[13] = (now_blocks >> 8) & 0xff; + + /* Read/Write from ahci */ + if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis), + user_buffer, user_buffer_size, + is_write)) { + debug("scsi_ahci: SCSI %s10 command failure.\n", + is_write ? "WRITE" : "READ"); + return -EIO; + } + + /* If this transaction is a write, do a following flush. + * Writes in u-boot are so rare, and the logic to know when is + * the last write and do a flush only there is sufficiently + * difficult. Just do a flush after every write. This incurs, + * usually, one extra flush when the rare writes do happen. + */ + if (is_write) { + if (-EIO == ata_io_flush(pccb->target)) + return -EIO; + } + user_buffer += transfer_size; + user_buffer_size -= transfer_size; + blocks -= now_blocks; + lba += now_blocks; } return 0; @@ -609,6 +770,7 @@ static int ata_scsiop_read10(ccb * pccb) static int ata_scsiop_read_capacity10(ccb *pccb) { u32 cap; + u32 block_size; if (!ataid[pccb->target]) { printf("scsi_ahci: SCSI READ CAPACITY10 command failure. " @@ -618,11 +780,52 @@ static int ata_scsiop_read_capacity10(ccb *pccb) } cap = le32_to_cpu(ataid[pccb->target]->lba_capacity); + if (cap == 0xfffffff) { + unsigned short *cap48 = ataid[pccb->target]->lba48_capacity; + if (cap48[2] || cap48[3]) { + cap = 0xffffffff; + } else { + cap = (le16_to_cpu(cap48[1]) << 16) | + (le16_to_cpu(cap48[0])); + } + } + + cap = cpu_to_be32(cap); + memcpy(pccb->pdata, &cap, sizeof(cap)); + + block_size = cpu_to_be32((u32)512); + memcpy(&pccb->pdata[4], &block_size, 4); + + return 0; +} + + +/* + * SCSI READ CAPACITY16 command operation. + */ +static int ata_scsiop_read_capacity16(ccb *pccb) +{ + u64 cap; + u64 block_size; + + if (!ataid[pccb->target]) { + printf("scsi_ahci: SCSI READ CAPACITY16 command failure. " + "\tNo ATA info!\n" + "\tPlease run SCSI commmand INQUIRY firstly!\n"); + return -EPERM; + } + + cap = le32_to_cpu(ataid[pccb->target]->lba_capacity); + if (cap == 0xfffffff) { + memcpy(&cap, ataid[pccb->target]->lba48_capacity, sizeof(cap)); + cap = le64_to_cpu(cap); + } + + cap = cpu_to_be64(cap); memcpy(pccb->pdata, &cap, sizeof(cap)); - pccb->pdata[4] = pccb->pdata[5] = 0; - pccb->pdata[6] = 512 >> 8; - pccb->pdata[7] = 512 & 0xff; + block_size = cpu_to_be64((u64)512); + memcpy(&pccb->pdata[8], &block_size, 8); return 0; } @@ -643,11 +846,17 @@ int scsi_exec(ccb *pccb) switch (pccb->cmd[0]) { case SCSI_READ10: - ret = ata_scsiop_read10(pccb); + ret = ata_scsiop_read_write(pccb, 0); break; - case SCSI_RD_CAPAC: + case SCSI_WRITE10: + ret = ata_scsiop_read_write(pccb, 1); + break; + case SCSI_RD_CAPAC10: ret = ata_scsiop_read_capacity10(pccb); break; + case SCSI_RD_CAPAC16: + ret = ata_scsiop_read_capacity16(pccb); + break; case SCSI_TST_U_RDY: ret = ata_scsiop_test_unit_ready(pccb); break; @@ -685,7 +894,9 @@ void scsi_low_level_init(int busdevfunc) printf("Can not start port %d\n", i); continue; } +#ifdef CONFIG_AHCI_SETFEATURES_XFER ahci_set_feature((u8) i); +#endif } } } @@ -726,7 +937,9 @@ int ahci_init(u32 base) printf("Can not start port %d\n", i); continue; } +#ifdef CONFIG_AHCI_SETFEATURES_XFER ahci_set_feature((u8) i); +#endif } } err_out: @@ -734,6 +947,42 @@ err_out: } #endif +/* + * In the general case of generic rotating media it makes sense to have a + * flush capability. It probably even makes sense in the case of SSDs because + * one cannot always know for sure what kind of internal cache/flush mechanism + * is embodied therein. At first it was planned to invoke this after the last + * write to disk and before rebooting. In practice, knowing, a priori, which + * is the last write is difficult. Because writing to the disk in u-boot is + * very rare, this flush command will be invoked after every block write. + */ +static int ata_io_flush(u8 port) +{ + u8 fis[20]; + struct ahci_ioports *pp = &(probe_ent->port[port]); + volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio; + u32 cmd_fis_len = 5; /* five dwords */ + + /* Preset the FIS */ + memset(fis, 0, 20); + fis[0] = 0x27; /* Host to device FIS. */ + fis[1] = 1 << 7; /* Command FIS. */ + fis[2] = ATA_CMD_FLUSH_EXT; + + memcpy((unsigned char *)pp->cmd_tbl, fis, 20); + ahci_fill_cmd_slot(pp, cmd_fis_len); + writel_with_flush(1, port_mmio + PORT_CMD_ISSUE); + + if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, + WAIT_MS_FLUSH, 0x1)) { + debug("scsi_ahci: flush command timeout on port %d.\n", port); + return -EIO; + } + + return 0; +} + + void scsi_bus_reset(void) { /*Not implement*/ diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c index fda3389..1f9d7b0 100644 --- a/drivers/block/fsl_sata.c +++ b/drivers/block/fsl_sata.c @@ -56,25 +56,6 @@ static inline void sdelay(unsigned long sec) mdelay(1000); } -void dprint_buffer(unsigned char *buf, int len) -{ - int i, j; - - i = 0; - j = 0; - printf("\n\r"); - - for (i = 0; i < len; i++) { - printf("%02x ", *buf++); - j++; - if (j == 16) { - printf("\n\r"); - j = 0; - } - } - printf("\n\r"); -} - static void fsl_sata_dump_sfis(struct sata_fis_d2h *s) { printf("Status FIS dump:\n\r"); @@ -94,7 +75,7 @@ static void fsl_sata_dump_sfis(struct sata_fis_d2h *s) printf("sector_count_exp: %02x\n\r", s->sector_count_exp); } -static int ata_wait_register(volatile unsigned *addr, u32 mask, +static int ata_wait_register(unsigned __iomem *addr, u32 mask, u32 val, u32 timeout_msec) { int i; @@ -112,7 +93,7 @@ int init_sata(int dev) cmd_hdr_tbl_t *cmd_hdr; u32 cda; u32 val32; - fsl_sata_reg_t *reg; + fsl_sata_reg_t __iomem *reg; u32 sig; int i; fsl_sata_t *sata; @@ -287,42 +268,7 @@ int init_sata(int dev) return 0; } -/* Hardware reset, like Power-on and COMRESET */ -void fsl_sata_hardware_reset(u32 reg_base) -{ - fsl_sata_reg_t *reg = (fsl_sata_reg_t *)reg_base; - u32 scontrol; - - /* Disable the SATA interface and put PHY offline */ - scontrol = in_le32(®->scontrol); - scontrol = (scontrol & 0x0f0) | 0x304; - out_le32(®->scontrol, scontrol); - - /* No speed strict */ - scontrol = in_le32(®->scontrol); - scontrol = scontrol & ~0x0f0; - out_le32(®->scontrol, scontrol); - - /* Issue PHY wake/reset, Hardware_reset_asserted */ - scontrol = in_le32(®->scontrol); - scontrol = (scontrol & 0x0f0) | 0x301; - out_le32(®->scontrol, scontrol); - - mdelay(100); - - /* Resume PHY, COMRESET negated, the device initialize hardware - * and execute diagnostics, send good status-signature to host, - * which is D2H register FIS, and then the device enter idle state. - */ - scontrol = in_le32(®->scontrol); - scontrol = (scontrol & 0x0f0) | 0x300; - out_le32(®->scontrol, scontrol); - - mdelay(100); - return; -} - -static void fsl_sata_dump_regs(fsl_sata_reg_t *reg) +static void fsl_sata_dump_regs(fsl_sata_reg_t __iomem *reg) { printf("\n\rSATA: %08x\n\r", (u32)reg); printf("CQR: %08x\n\r", in_le32(®->cqr)); @@ -363,7 +309,7 @@ static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis u32 prde_count; u32 val32; u32 ttl; - fsl_sata_reg_t *reg = sata->reg_base; + fsl_sata_reg_t __iomem *reg = sata->reg_base; int i; /* Check xfer length */ @@ -620,7 +566,7 @@ static u32 fsl_sata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_wr return blkcnt; } -void fsl_sata_flush_cache(int dev) +static void fsl_sata_flush_cache(int dev) { fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d, *cfis = &h2d; @@ -664,7 +610,8 @@ static u32 fsl_sata_rw_cmd_ext(int dev, u32 start, u32 blkcnt, u8 *buffer, int i return blkcnt; } -u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write) +static u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, + int is_write) { fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d, *cfis = &h2d; @@ -707,7 +654,7 @@ u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write return blkcnt; } -void fsl_sata_flush_cache_ext(int dev) +static void fsl_sata_flush_cache_ext(int dev) { fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d, *cfis = &h2d; @@ -721,12 +668,6 @@ void fsl_sata_flush_cache_ext(int dev) fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0); } -/* Software reset, set SRST of the Device Control register */ -void fsl_sata_software_reset(int dev) -{ - return; -} - static void fsl_sata_init_wcache(int dev, u16 *id) { fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; @@ -757,7 +698,7 @@ static int fsl_sata_get_flush_ext(int dev) return sata->flush_ext; } -u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, +static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, const void *buffer, int is_write) { u32 start, blks; @@ -792,8 +733,8 @@ u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, return blkcnt; } -u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt, const void *buffer, - int is_write) +static u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt, + const void *buffer, int is_write) { u32 start, blks; u8 *addr; diff --git a/drivers/block/fsl_sata.h b/drivers/block/fsl_sata.h index cecff68..a9c27bc 100644 --- a/drivers/block/fsl_sata.h +++ b/drivers/block/fsl_sata.h @@ -176,10 +176,11 @@ typedef struct fsl_sata_reg { * Command Header Entry */ typedef struct cmd_hdr_entry { - u32 cda; /* Command Descriptor Address, 4 bytes aligned */ - u32 prde_fis_len; /* Number of PRD entries and FIS length */ - u32 ttl; /* Total transfer length */ - u32 attribute; /* the attribute of command */ + __le32 cda; /* Command Descriptor Address, + 4 bytes aligned */ + __le32 prde_fis_len; /* Number of PRD entries and FIS length */ + __le32 ttl; /* Total transfer length */ + __le32 attribute; /* the attribute of command */ } __attribute__ ((packed)) cmd_hdr_entry_t; #define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry) @@ -230,10 +231,10 @@ typedef struct cmd_hdr_tbl { * PRD entry - Physical Region Descriptor entry */ typedef struct prd_entry { - u32 dba; /* Data base address, 4 bytes aligned */ + __le32 dba; /* Data base address, 4 bytes aligned */ u32 res1; u32 res2; - u32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */ + __le32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */ } __attribute__ ((packed)) prd_entry_t; #define SATA_HC_CMD_DESC_PRD_SIZE sizeof(struct prd_entry) diff --git a/drivers/block/sata_sil.c b/drivers/block/sata_sil.c index 245b872..b70f04d 100644 --- a/drivers/block/sata_sil.c +++ b/drivers/block/sata_sil.c @@ -27,6 +27,7 @@ #include <fis.h> #include <sata.h> #include <libata.h> +#include <sata.h> #include "sata_sil.h" /* Convert sectorsize to wordsize */ @@ -369,8 +370,8 @@ static ulong sil_sata_rw_cmd_ext(int dev, ulong start, ulong blkcnt, return blkcnt; } -ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt, + const void *buffer, int is_write) { ulong start, blks, max_blks; u8 *addr; @@ -397,8 +398,8 @@ ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt, return blkcnt; } -ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt, + const void *buffer, int is_write) { ulong start, blks, max_blks; u8 *addr; @@ -427,7 +428,7 @@ ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt, return blkcnt; } -void sil_sata_cmd_flush_cache(int dev) +static void sil_sata_cmd_flush_cache(int dev) { struct sil_cmd_block cmdb, *pcmd = &cmdb; @@ -439,7 +440,7 @@ void sil_sata_cmd_flush_cache(int dev) sil_exec_cmd(dev, pcmd, 0); } -void sil_sata_cmd_flush_cache_ext(int dev) +static void sil_sata_cmd_flush_cache_ext(int dev) { struct sil_cmd_block cmdb, *pcmd = &cmdb; diff --git a/drivers/gpio/mpc83xx_gpio.c b/drivers/gpio/mpc83xx_gpio.c index a9afcb2..e167852 100644 --- a/drivers/gpio/mpc83xx_gpio.c +++ b/drivers/gpio/mpc83xx_gpio.c @@ -163,7 +163,7 @@ int gpio_set_value(unsigned gpio, int value) } /* Configure GPIO registers early */ -void mpc83xx_gpio_init_f() +void mpc83xx_gpio_init_f(void) { immap_t *im = (immap_t *)CONFIG_SYS_IMMR; @@ -187,7 +187,7 @@ void mpc83xx_gpio_init_f() } /* Initialize GPIO soft-copies */ -void mpc83xx_gpio_init_r() +void mpc83xx_gpio_init_r(void) { #if MPC83XX_GPIO_CTRLRS >= 1 gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE; diff --git a/drivers/input/input.c b/drivers/input/input.c index 9800667..04fa5f0 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -110,7 +110,7 @@ static struct { /* Maximum number of output characters that an ANSI sequence expands to */ #define ANSI_CHAR_MAX 3 -int input_queue_ascii(struct input_config *config, int ch) +static int input_queue_ascii(struct input_config *config, int ch) { if (config->fifo_in + 1 == INPUT_BUFFER_LEN) { if (!config->fifo_out) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 3f8d30d..e93e38a 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -68,7 +68,7 @@ struct fsl_esdhc { }; /* Return the XFERTYP flags for a given command and data packet */ -uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) +static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) { uint xfertyp = 0; @@ -410,12 +410,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) return 0; } -void set_sysctl(struct mmc *mmc, uint clock) +static void set_sysctl(struct mmc *mmc, uint clock) { - int sdhc_clk = gd->sdhc_clk; int div, pre_div; struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; + int sdhc_clk = cfg->sdhc_clk; uint clk; if (clock < mmc->f_min) @@ -598,6 +598,7 @@ int fsl_esdhc_mmc_init(bd_t *bis) cfg = malloc(sizeof(struct fsl_esdhc_cfg)); memset(cfg, 0, sizeof(struct fsl_esdhc_cfg)); cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR; + cfg->sdhc_clk = gd->sdhc_clk; return fsl_esdhc_initialize(bis, cfg); } diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 5fbf956..5ffd8c5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -47,7 +47,8 @@ int __board_mmc_getcd(struct mmc *mmc) { int board_mmc_getcd(struct mmc *mmc)__attribute__((weak, alias("__board_mmc_getcd"))); -int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) { struct mmc_data backup; int ret; @@ -108,7 +109,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) return ret; } -int mmc_send_status(struct mmc *mmc, int timeout) +static int mmc_send_status(struct mmc *mmc, int timeout) { struct mmc_cmd cmd; int err, retries = 5; @@ -152,7 +153,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) return 0; } -int mmc_set_blocklen(struct mmc *mmc, int len) +static int mmc_set_blocklen(struct mmc *mmc, int len) { struct mmc_cmd cmd; @@ -345,7 +346,8 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) return blkcnt; } -int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) +static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, + lbaint_t blkcnt) { struct mmc_cmd cmd; struct mmc_data data; @@ -415,7 +417,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst) return blkcnt; } -int mmc_go_idle(struct mmc* mmc) +static int mmc_go_idle(struct mmc *mmc) { struct mmc_cmd cmd; int err; @@ -436,8 +438,7 @@ int mmc_go_idle(struct mmc* mmc) return 0; } -int -sd_send_op_cond(struct mmc *mmc) +static int sd_send_op_cond(struct mmc *mmc) { int timeout = 1000; int err; @@ -502,7 +503,7 @@ sd_send_op_cond(struct mmc *mmc) return 0; } -int mmc_send_op_cond(struct mmc *mmc) +static int mmc_send_op_cond(struct mmc *mmc) { int timeout = 10000; struct mmc_cmd cmd; @@ -566,7 +567,7 @@ int mmc_send_op_cond(struct mmc *mmc) } -int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) +static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) { struct mmc_cmd cmd; struct mmc_data data; @@ -588,7 +589,7 @@ int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) } -int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) +static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) { struct mmc_cmd cmd; int timeout = 1000; @@ -610,7 +611,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) } -int mmc_change_freq(struct mmc *mmc) +static int mmc_change_freq(struct mmc *mmc) { ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); char cardtype; @@ -680,7 +681,7 @@ int mmc_getcd(struct mmc *mmc) return cd; } -int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) +static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) { struct mmc_cmd cmd; struct mmc_data data; @@ -701,7 +702,7 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) } -int sd_change_freq(struct mmc *mmc) +static int sd_change_freq(struct mmc *mmc) { int err; struct mmc_cmd cmd; @@ -840,7 +841,7 @@ static const int multipliers[] = { 80, }; -void mmc_set_ios(struct mmc *mmc) +static void mmc_set_ios(struct mmc *mmc) { mmc->set_ios(mmc); } @@ -858,14 +859,14 @@ void mmc_set_clock(struct mmc *mmc, uint clock) mmc_set_ios(mmc); } -void mmc_set_bus_width(struct mmc *mmc, uint width) +static void mmc_set_bus_width(struct mmc *mmc, uint width) { mmc->bus_width = width; mmc_set_ios(mmc); } -int mmc_startup(struct mmc *mmc) +static int mmc_startup(struct mmc *mmc) { int err, width; uint mult, freq; @@ -1013,7 +1014,7 @@ int mmc_startup(struct mmc *mmc) if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { /* check ext_csd version and capacity */ err = mmc_send_ext_csd(mmc, ext_csd); - if (!err & (ext_csd[EXT_CSD_REV] >= 2)) { + if (!err && (ext_csd[EXT_CSD_REV] >= 2)) { /* * According to the JEDEC Standard, the value of * ext_csd's capacity is valid if the value is more @@ -1148,7 +1149,7 @@ int mmc_startup(struct mmc *mmc) return 0; } -int mmc_send_if_cond(struct mmc *mmc) +static int mmc_send_if_cond(struct mmc *mmc) { struct mmc_cmd cmd; int err; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 43140f3..b2dfc53 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -752,8 +752,8 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c) */ static flash_sect_t find_sector (flash_info_t * info, ulong addr) { - static flash_sect_t saved_sector = 0; /* previously found sector */ - static flash_info_t *saved_info = 0; /* previously used flash bank */ + static flash_sect_t saved_sector; /* previously found sector */ + static flash_info_t *saved_info; /* previously used flash bank */ flash_sect_t sector = saved_sector; if ((info != saved_info) || (sector >= info->sector_count)) @@ -1147,8 +1147,9 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) } if (use_flash_status_poll(info)) { - cfiword_t cword = (cfiword_t)0xffffffffffffffffULL; + cfiword_t cword; void *dest; + cword.ll = 0xffffffffffffffffULL; dest = flash_map(info, sect, 0); st = flash_status_poll(info, &cword, dest, info->erase_blk_tout, "erase"); @@ -1430,8 +1431,8 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) static int cfi_protect_bugfix(flash_info_t *info, long sector, int prot) { - if ((info->manufacturer_id == (uchar)INTEL_MANUFACT) && - (info->device_id == NUMONYX_256MBIT)) { + if (info->manufacturer_id == ((INTEL_MANUFACT & FLASH_VENDMASK) >> 16) + && info->device_id == NUMONYX_256MBIT) { /* * see errata called * "Numonyx Axcell P33/P30 Specification Update" :) @@ -1487,7 +1488,8 @@ int flash_real_protect (flash_info_t * info, long sector, int prot) case CFI_CMDSET_AMD_EXTENDED: case CFI_CMDSET_AMD_STANDARD: /* U-Boot only checks the first byte */ - if (info->manufacturer_id == (uchar)ATM_MANUFACT) { + if (info->manufacturer_id == + ((ATM_MANUFACT & FLASH_VENDMASK) >> 16)) { if (prot) { flash_unlock_seq (info, 0); flash_write_cmd (info, 0, @@ -1505,7 +1507,8 @@ int flash_real_protect (flash_info_t * info, long sector, int prot) 0, ATM_CMD_UNLOCK_SECT); } } - if (info->manufacturer_id == (uchar)AMD_MANUFACT) { + if (info->manufacturer_id == + ((AMD_MANUFACT & FLASH_VENDMASK) >> 16)) { int flag = disable_interrupts(); int lock_flag; @@ -1735,7 +1738,8 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry) flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI); #ifdef CONFIG_SYS_FLASH_PROTECTION - if (info->ext_addr && info->manufacturer_id == (uchar)AMD_MANUFACT) { + if (info->ext_addr && info->manufacturer_id == + ((AMD_MANUFACT & FLASH_VENDMASK) >> 16)) { ushort spus; /* read sector protect/unprotect scheme */ @@ -1854,7 +1858,7 @@ static void flash_read_cfi (flash_info_t *info, void *buf, p[i] = flash_read_uchar(info, start + i); } -void __flash_cmd_reset(flash_info_t *info) +static void __flash_cmd_reset(flash_info_t *info) { /* * We do not yet know what kind of commandset to use, so we issue diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 71f5027..d3b71a5 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2601,6 +2601,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, int *maf_id, int *dev_id, const struct nand_flash_dev *type) { + const char *name; int i, maf_idx; u8 id_data[8]; int ret; @@ -2848,14 +2849,14 @@ ident_done: chip->cmdfunc = nand_command_lp; /* TODO onfi flash name */ - MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, - nand_manuf_ids[maf_idx].name, + name = type->name; #ifdef CONFIG_SYS_NAND_ONFI_DETECTION - chip->onfi_version ? chip->onfi_params.model : type->name); -#else - type->name); + if (chip->onfi_version) + name = chip->onfi_params.model; #endif + MTDDEBUG(MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, + nand_manuf_ids[maf_idx].name, name); return type; } diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 81f0e08..097cf62 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -39,6 +39,7 @@ #include <asm/errno.h> #include <linux/mtd/mtd.h> +#include <linux/mtd/nand_ecc.h> /* The PPC4xx NDFC uses Smart Media (SMC) bytes order */ #ifdef CONFIG_NAND_NDFC diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c index 5408c51..4d94cc6 100644 --- a/drivers/mtd/nand/tegra_nand.c +++ b/drivers/mtd/nand/tegra_nand.c @@ -219,6 +219,34 @@ static uint8_t read_byte(struct mtd_info *mtd) } /** + * Read len bytes from the chip into a buffer + * + * @param mtd MTD device structure + * @param buf buffer to store data to + * @param len number of bytes to read + * + * Read function for 8bit bus-width + */ +static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + int i, s; + unsigned int reg; + struct nand_chip *chip = mtd->priv; + struct nand_drv *info = (struct nand_drv *)chip->priv; + + for (i = 0; i < len; i += 4) { + s = (len - i) > 4 ? 4 : len - i; + writel(CMD_PIO | CMD_RX | CMD_A_VALID | CMD_CE0 | + ((s - 1) << CMD_TRANS_SIZE_SHIFT) | CMD_GO, + &info->reg->command); + if (!nand_waitfor_cmd_completion(info->reg)) + puts("Command timeout during read_buf\n"); + reg = readl(&info->reg->resp); + memcpy(buf + i, ®, s); + } +} + +/** * Check NAND status to see if it is ready or not * * @param mtd MTD device structure @@ -317,6 +345,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, switch (command) { case NAND_CMD_READID: writel(NAND_CMD_READID, &info->reg->cmd_reg1); + writel(column & 0xFF, &info->reg->addr_reg1); writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_PIO | CMD_RX | ((4 - 1) << CMD_TRANS_SIZE_SHIFT) @@ -324,6 +353,12 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, &info->reg->command); info->pio_byte_index = 0; break; + case NAND_CMD_PARAM: + writel(NAND_CMD_PARAM, &info->reg->cmd_reg1); + writel(column & 0xFF, &info->reg->addr_reg1); + writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0, + &info->reg->command); + break; case NAND_CMD_READ0: writel(NAND_CMD_READ0, &info->reg->cmd_reg1); writel(NAND_CMD_READSTART, &info->reg->cmd_reg2); @@ -976,6 +1011,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum) nand->options = LP_OPTIONS; nand->cmdfunc = nand_command; nand->read_byte = read_byte; + nand->read_buf = read_buf; nand->ecc.read_page = nand_read_page_hwecc; nand->ecc.write_page = nand_write_page_hwecc; nand->ecc.read_page_raw = nand_read_page_raw; diff --git a/drivers/mtd/ubi/crc32.c b/drivers/mtd/ubi/crc32.c index a7e26b0..ab439b3 100644 --- a/drivers/mtd/ubi/crc32.c +++ b/drivers/mtd/ubi/crc32.c @@ -38,17 +38,9 @@ #include "crc32defs.h" #define CRC_LE_BITS 8 -# define __force -#ifndef __constant_cpu_to_le32 -#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x)) -#endif -#ifndef __constant_le32_to_cpu -#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x)) -#endif - #if CRC_LE_BITS == 8 -#define tole(x) __constant_cpu_to_le32(x) -#define tobe(x) __constant_cpu_to_be32(x) +#define tole(x) cpu_to_le32(x) +#define tobe(x) cpu_to_be32(x) #else #define tole(x) (x) #define tobe(x) (x) diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index 82c787b..54b142f 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -46,7 +46,7 @@ static int num_controllers; TBICR_FULL_DUPLEX | TBICR_SPEED1_SET) /* Configure the TBI for SGMII operation */ -void dtsec_configure_serdes(struct fm_eth *priv) +static void dtsec_configure_serdes(struct fm_eth *priv) { #ifdef CONFIG_SYS_FMAN_V3 u32 value; diff --git a/drivers/net/fm/p1023.c b/drivers/net/fm/p1023.c index 9765da5..387d2a3 100644 --- a/drivers/net/fm/p1023.c +++ b/drivers/net/fm/p1023.c @@ -23,7 +23,7 @@ #include <asm/immap_85xx.h> #include <asm/fsl_serdes.h> -u32 port_to_devdisr[] = { +static u32 port_to_devdisr[] = { [FM1_DTSEC1] = MPC85xx_DEVDISR_TSEC1, [FM1_DTSEC2] = MPC85xx_DEVDISR_TSEC2, }; diff --git a/drivers/net/fm/p4080.c b/drivers/net/fm/p4080.c index 9dc6049..b04fd0f 100644 --- a/drivers/net/fm/p4080.c +++ b/drivers/net/fm/p4080.c @@ -23,7 +23,7 @@ #include <asm/immap_85xx.h> #include <asm/fsl_serdes.h> -u32 port_to_devdisr[] = { +static u32 port_to_devdisr[] = { [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, diff --git a/drivers/net/fm/p5020.c b/drivers/net/fm/p5020.c index a7a6e43..5391044 100644 --- a/drivers/net/fm/p5020.c +++ b/drivers/net/fm/p5020.c @@ -23,7 +23,7 @@ #include <asm/immap_85xx.h> #include <asm/fsl_serdes.h> -u32 port_to_devdisr[] = { +static u32 port_to_devdisr[] = { [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, diff --git a/drivers/net/fm/tgec_phy.c b/drivers/net/fm/tgec_phy.c index 2d349ad..2be69d7 100644 --- a/drivers/net/fm/tgec_phy.c +++ b/drivers/net/fm/tgec_phy.c @@ -30,8 +30,8 @@ * until the write is done before it returns. All PHY configuration has to be * done through the TSEC1 MIIM regs */ -int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, - int regnum, u16 value) +static int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, + int regnum, u16 value) { u32 mdio_ctl; u32 stat_val; @@ -72,8 +72,8 @@ int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, * Clears miimcom first. All PHY configuration has to be done through the * TSEC1 MIIM regs */ -int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, - int regnum) +static int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, + int regnum) { u32 mdio_ctl; u32 stat_val; @@ -114,7 +114,7 @@ int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, return in_be32(®s->mdio_data) & 0xffff; } -int tgec_mdio_reset(struct mii_dev *bus) +static int tgec_mdio_reset(struct mii_dev *bus) { return 0; } diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 0e1ced7..8bacbda 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -51,8 +51,6 @@ #include "macb.h" -#define barrier() asm volatile("" ::: "memory") - #define CONFIG_SYS_MACB_RX_BUFFER_SIZE 4096 #define CONFIG_SYS_MACB_RX_RING_SIZE (CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128) #define CONFIG_SYS_MACB_TX_RING_SIZE 16 diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c index 798473d..9b3808b 100644 --- a/drivers/net/phy/atheros.c +++ b/drivers/net/phy/atheros.c @@ -30,7 +30,7 @@ static int ar8021_config(struct phy_device *phydev) return 0; } -struct phy_driver AR8021_driver = { +static struct phy_driver AR8021_driver = { .name = "AR8021", .uid = 0x4dd040, .mask = 0xfffff0, diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index baef60f..1ffa791 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -43,7 +43,7 @@ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement * hasn't changed, and > 0 if it has changed. */ -int genphy_config_advert(struct phy_device *phydev) +static int genphy_config_advert(struct phy_device *phydev) { u32 advertise; int oldadv, adv; @@ -118,7 +118,7 @@ int genphy_config_advert(struct phy_device *phydev) * Description: Configures MII_BMCR to force speed/duplex * to the values in phydev. Assumes that the values are valid. */ -int genphy_setup_forced(struct phy_device *phydev) +static int genphy_setup_forced(struct phy_device *phydev) { int err; int ctl = 0; @@ -465,7 +465,7 @@ int phy_register(struct phy_driver *drv) return 0; } -int phy_probe(struct phy_device *phydev) +static int phy_probe(struct phy_device *phydev) { int err = 0; @@ -488,7 +488,7 @@ static struct phy_driver *generic_for_interface(phy_interface_t interface) return &genphy_driver; } -struct phy_driver *get_phy_driver(struct phy_device *phydev, +static struct phy_driver *get_phy_driver(struct phy_device *phydev, phy_interface_t interface) { struct list_head *entry; @@ -505,8 +505,9 @@ struct phy_driver *get_phy_driver(struct phy_device *phydev, return generic_for_interface(interface); } -struct phy_device *phy_device_create(struct mii_dev *bus, int addr, int phy_id, - phy_interface_t interface) +static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, + int phy_id, + phy_interface_t interface) { struct phy_device *dev; @@ -549,7 +550,7 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr, int phy_id, * Description: Reads the ID registers of the PHY at @addr on the * @bus, stores it in @phy_id and returns zero on success. */ -int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) +static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) { int phy_reg; @@ -581,8 +582,8 @@ int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) * Description: Reads the ID registers of the PHY at @addr on the * @bus, then allocates and returns the phy_device to represent it. */ -struct phy_device *get_phy_device(struct mii_dev *bus, int addr, - phy_interface_t interface) +static struct phy_device *get_phy_device(struct mii_dev *bus, int addr, + phy_interface_t interface) { u32 phy_id = 0x1fffffff; int i; diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 0a0f40d..6c5cb99 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -123,7 +123,7 @@ static int cis8204_config(struct phy_device *phydev) } /* Vitesse VSC8601 */ -int vsc8601_config(struct phy_device *phydev) +static int vsc8601_config(struct phy_device *phydev) { /* Configure some basic stuff */ #ifdef CONFIG_SYS_VSC8601_SKEWFIX diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c index 6dc7ad5..1357ede 100644 --- a/drivers/net/smc91111.c +++ b/drivers/net/smc91111.c @@ -178,8 +178,6 @@ static void smc_phy_configure(struct eth_device *dev); * inx,outx functions fixed this problem. */ -#define barrier() __asm__ __volatile__("": : :"memory") - static inline word SMC_inw(struct eth_device *dev, dword offset) { word v; diff --git a/drivers/net/vsc7385.c b/drivers/net/vsc7385.c index ada42c4..a5110e5 100644 --- a/drivers/net/vsc7385.c +++ b/drivers/net/vsc7385.c @@ -16,6 +16,7 @@ #include <common.h> #include <asm/io.h> #include <asm/errno.h> +#include "vsc7385.h" /* * Upload a Vitesse VSC7385 firmware image to the hardware diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c index ea8d734..f53c2bf 100644 --- a/drivers/serial/s3c64xx.c +++ b/drivers/serial/s3c64xx.c @@ -40,8 +40,6 @@ DECLARE_GLOBAL_DATA_PTR; #error "Bad: you didn't configure serial ..." #endif -#define barrier() asm volatile("" ::: "memory") - /* * The coefficient, used to calculate the baudrate on S3C6400 UARTs is * calculated as diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index 4176e25..c1c0134 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -34,7 +34,7 @@ DECLARE_GLOBAL_DATA_PTR; #if !defined(CONFIG_CONS_INDEX) -#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4) +#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6) #error "Invalid console index value." #endif @@ -46,12 +46,16 @@ DECLARE_GLOBAL_DATA_PTR; #error "Console port 3 defined but not configured." #elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4) #error "Console port 4 defined but not configured." +#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5) +#error "Console port 5 defined but not configured." +#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6) +#error "Console port 6 defined but not configured." #endif /* Note: The port number specified in the functions is 1 based. * the array is 0 based. */ -static NS16550_t serial_ports[4] = { +static NS16550_t serial_ports[6] = { #ifdef CONFIG_SYS_NS16550_COM1 (NS16550_t)CONFIG_SYS_NS16550_COM1, #else @@ -68,7 +72,17 @@ static NS16550_t serial_ports[4] = { NULL, #endif #ifdef CONFIG_SYS_NS16550_COM4 - (NS16550_t)CONFIG_SYS_NS16550_COM4 + (NS16550_t)CONFIG_SYS_NS16550_COM4, +#else + NULL, +#endif +#ifdef CONFIG_SYS_NS16550_COM5 + (NS16550_t)CONFIG_SYS_NS16550_COM5, +#else + NULL, +#endif +#ifdef CONFIG_SYS_NS16550_COM6 + (NS16550_t)CONFIG_SYS_NS16550_COM6 #else NULL #endif @@ -78,21 +92,33 @@ static NS16550_t serial_ports[4] = { /* Multi serial device functions */ #define DECLARE_ESERIAL_FUNCTIONS(port) \ - static int eserial##port##_init (void) {\ - int clock_divisor; \ - clock_divisor = calc_divisor(serial_ports[port-1]); \ - NS16550_init(serial_ports[port-1], clock_divisor); \ - return(0);}\ - static void eserial##port##_setbrg (void) {\ - serial_setbrg_dev(port);}\ - static int eserial##port##_getc (void) {\ - return serial_getc_dev(port);}\ - static int eserial##port##_tstc (void) {\ - return serial_tstc_dev(port);}\ - static void eserial##port##_putc (const char c) {\ - serial_putc_dev(port, c);}\ - static void eserial##port##_puts (const char *s) {\ - serial_puts_dev(port, s);} + static int eserial##port##_init(void) \ + { \ + int clock_divisor; \ + clock_divisor = calc_divisor(serial_ports[port-1]); \ + NS16550_init(serial_ports[port-1], clock_divisor); \ + return 0 ; \ + } \ + static void eserial##port##_setbrg(void) \ + { \ + serial_setbrg_dev(port); \ + } \ + static int eserial##port##_getc(void) \ + { \ + return serial_getc_dev(port); \ + } \ + static int eserial##port##_tstc(void) \ + { \ + return serial_tstc_dev(port); \ + } \ + static void eserial##port##_putc(const char c) \ + { \ + serial_putc_dev(port, c); \ + } \ + static void eserial##port##_puts(const char *s) \ + { \ + serial_puts_dev(port, s); \ + } /* Serial device descriptor */ #define INIT_ESERIAL_STRUCTURE(port, __name) { \ @@ -231,6 +257,12 @@ struct serial_device eserial3_device = DECLARE_ESERIAL_FUNCTIONS(4); struct serial_device eserial4_device = INIT_ESERIAL_STRUCTURE(4, "eserial3"); +DECLARE_ESERIAL_FUNCTIONS(5); +struct serial_device eserial5_device = + INIT_ESERIAL_STRUCTURE(5, "eserial4"); +DECLARE_ESERIAL_FUNCTIONS(6); +struct serial_device eserial6_device = + INIT_ESERIAL_STRUCTURE(6, "eserial5"); __weak struct serial_device *default_serial_console(void) { @@ -242,6 +274,10 @@ __weak struct serial_device *default_serial_console(void) return &eserial3_device; #elif CONFIG_CONS_INDEX == 4 return &eserial4_device; +#elif CONFIG_CONS_INDEX == 5 + return &eserial5_device; +#elif CONFIG_CONS_INDEX == 6 + return &eserial6_device; #else #error "Bad CONFIG_CONS_INDEX." #endif @@ -261,4 +297,10 @@ void ns16550_serial_initialize(void) #if defined(CONFIG_SYS_NS16550_COM4) serial_register(&eserial4_device); #endif +#if defined(CONFIG_SYS_NS16550_COM5) + serial_register(&eserial5_device); +#endif +#if defined(CONFIG_SYS_NS16550_COM6) + serial_register(&eserial6_device); +#endif } diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 1e187e5..8b24e00 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1978,8 +1978,8 @@ static int is_eth_addr_valid(char *str) p = q; } - if (i == 6) /* it looks ok */ - return 1; + /* Now check the contents. */ + return is_valid_ether_addr(ea); } return 0; } diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 9f7794f..9c67b63 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -385,6 +385,13 @@ static u32 eorx, fgx, bgx; /* color pats */ static int cfb_do_flush_cache; +#ifdef CONFIG_CFB_CONSOLE_ANSI +static char ansi_buf[10]; +static int ansi_buf_size; +static int ansi_colors_need_revert; +static int ansi_cursor_hidden; +#endif + static const int video_font_draw_table8[] = { 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, @@ -768,9 +775,97 @@ static void console_back(void) } } -static void console_newline(void) +#ifdef CONFIG_CFB_CONSOLE_ANSI + +static void console_clear(void) +{ +#ifdef VIDEO_HW_RECTFILL + video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */ + 0, /* dest pos x */ + video_logo_height, /* dest pos y */ + VIDEO_VISIBLE_COLS, /* frame width */ + VIDEO_VISIBLE_ROWS, /* frame height */ + bgx /* fill color */ + ); +#else + memsetl(CONSOLE_ROW_FIRST, CONSOLE_SIZE, bgx); +#endif +} + +static void console_cursor_fix(void) +{ + if (console_row < 0) + console_row = 0; + if (console_row >= CONSOLE_ROWS) + console_row = CONSOLE_ROWS - 1; + if (console_col < 0) + console_col = 0; + if (console_col >= CONSOLE_COLS) + console_col = CONSOLE_COLS - 1; +} + +static void console_cursor_up(int n) +{ + console_row -= n; + console_cursor_fix(); +} + +static void console_cursor_down(int n) +{ + console_row += n; + console_cursor_fix(); +} + +static void console_cursor_left(int n) +{ + console_col -= n; + console_cursor_fix(); +} + +static void console_cursor_right(int n) +{ + console_col += n; + console_cursor_fix(); +} + +static void console_cursor_set_position(int row, int col) +{ + if (console_row != -1) + console_row = row; + if (console_col != -1) + console_col = col; + console_cursor_fix(); +} + +static void console_previousline(int n) { - console_row++; + /* FIXME: also scroll terminal ? */ + console_row -= n; + console_cursor_fix(); +} + +static void console_swap_colors(void) +{ + eorx = fgx; + fgx = bgx; + bgx = eorx; + eorx = fgx ^ bgx; +} + +static inline int console_cursor_is_visible(void) +{ + return !ansi_cursor_hidden; +} +#else +static inline int console_cursor_is_visible(void) +{ + return 1; +} +#endif + +static void console_newline(int n) +{ + console_row += n; console_col = 0; /* Check if we need to scroll the terminal */ @@ -779,7 +874,7 @@ static void console_newline(void) console_scrollup(); /* Decrement row number */ - console_row--; + console_row = CONSOLE_ROWS - 1; } } @@ -788,11 +883,12 @@ static void console_cr(void) console_col = 0; } -void video_putc(const char c) +static void parse_putc(const char c) { static int nl = 1; - CURSOR_OFF; + if (console_cursor_is_visible()) + CURSOR_OFF; switch (c) { case 13: /* back to first column */ @@ -801,7 +897,7 @@ void video_putc(const char c) case '\n': /* next line */ if (console_col || (!console_col && nl)) - console_newline(); + console_newline(1); nl = 1; break; @@ -810,7 +906,7 @@ void video_putc(const char c) console_col &= ~0x0007; if (console_col >= CONSOLE_COLS) - console_newline(); + console_newline(1); break; case 8: /* backspace */ @@ -827,11 +923,225 @@ void video_putc(const char c) /* check for newline */ if (console_col >= CONSOLE_COLS) { - console_newline(); + console_newline(1); nl = 0; } } - CURSOR_SET; + + if (console_cursor_is_visible()) + CURSOR_SET; +} + +void video_putc(const char c) +{ +#ifdef CONFIG_CFB_CONSOLE_ANSI + int i; + + if (c == 27) { + for (i = 0; i < ansi_buf_size; ++i) + parse_putc(ansi_buf[i]); + ansi_buf[0] = 27; + ansi_buf_size = 1; + return; + } + + if (ansi_buf_size > 0) { + /* + * 0 - ESC + * 1 - [ + * 2 - num1 + * 3 - .. + * 4 - ; + * 5 - num2 + * 6 - .. + * - cchar + */ + int next = 0; + + int flush = 0; + int fail = 0; + + int num1 = 0; + int num2 = 0; + int cchar = 0; + + ansi_buf[ansi_buf_size++] = c; + + if (ansi_buf_size >= sizeof(ansi_buf)) + fail = 1; + + for (i = 0; i < ansi_buf_size; ++i) { + if (fail) + break; + + switch (next) { + case 0: + if (ansi_buf[i] == 27) + next = 1; + else + fail = 1; + break; + + case 1: + if (ansi_buf[i] == '[') + next = 2; + else + fail = 1; + break; + + case 2: + if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') { + num1 = ansi_buf[i]-'0'; + next = 3; + } else if (ansi_buf[i] != '?') { + --i; + num1 = 1; + next = 4; + } + break; + + case 3: + if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') { + num1 *= 10; + num1 += ansi_buf[i]-'0'; + } else { + --i; + next = 4; + } + break; + + case 4: + if (ansi_buf[i] != ';') { + --i; + next = 7; + } else + next = 5; + break; + + case 5: + if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') { + num2 = ansi_buf[i]-'0'; + next = 6; + } else + fail = 1; + break; + + case 6: + if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') { + num2 *= 10; + num2 += ansi_buf[i]-'0'; + } else { + --i; + next = 7; + } + break; + + case 7: + if ((ansi_buf[i] >= 'A' && ansi_buf[i] <= 'H') + || ansi_buf[i] == 'J' + || ansi_buf[i] == 'K' + || ansi_buf[i] == 'h' + || ansi_buf[i] == 'l' + || ansi_buf[i] == 'm') { + cchar = ansi_buf[i]; + flush = 1; + } else + fail = 1; + break; + } + } + + if (fail) { + for (i = 0; i < ansi_buf_size; ++i) + parse_putc(ansi_buf[i]); + ansi_buf_size = 0; + return; + } + + if (flush) { + if (!ansi_cursor_hidden) + CURSOR_OFF; + ansi_buf_size = 0; + switch (cchar) { + case 'A': + /* move cursor num1 rows up */ + console_cursor_up(num1); + break; + case 'B': + /* move cursor num1 rows down */ + console_cursor_down(num1); + break; + case 'C': + /* move cursor num1 columns forward */ + console_cursor_right(num1); + break; + case 'D': + /* move cursor num1 columns back */ + console_cursor_left(num1); + break; + case 'E': + /* move cursor num1 rows up at begin of row */ + console_previousline(num1); + break; + case 'F': + /* move cursor num1 rows down at begin of row */ + console_newline(num1); + break; + case 'G': + /* move cursor to column num1 */ + console_cursor_set_position(-1, num1-1); + break; + case 'H': + /* move cursor to row num1, column num2 */ + console_cursor_set_position(num1-1, num2-1); + break; + case 'J': + /* clear console and move cursor to 0, 0 */ + console_clear(); + console_cursor_set_position(0, 0); + break; + case 'K': + /* clear line */ + if (num1 == 0) + console_clear_line(console_row, + console_col, + CONSOLE_COLS-1); + else if (num1 == 1) + console_clear_line(console_row, + 0, console_col); + else + console_clear_line(console_row, + 0, CONSOLE_COLS-1); + break; + case 'h': + ansi_cursor_hidden = 0; + break; + case 'l': + ansi_cursor_hidden = 1; + break; + case 'm': + if (num1 == 0) { /* reset swapped colors */ + if (ansi_colors_need_revert) { + console_swap_colors(); + ansi_colors_need_revert = 0; + } + } else if (num1 == 7) { /* once swap colors */ + if (!ansi_colors_need_revert) { + console_swap_colors(); + ansi_colors_need_revert = 1; + } + } + break; + } + if (!ansi_cursor_hidden) + CURSOR_SET; + } + } else { + parse_putc(c); + } +#else + parse_putc(c); +#endif } void video_puts(const char *s) diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c index 47b336e..ace226c 100644 --- a/drivers/video/mxc_ipuv3_fb.c +++ b/drivers/video/mxc_ipuv3_fb.c @@ -45,7 +45,7 @@ static int mxcfb_unmap_video_memory(struct fb_info *fbi); /* graphics setup */ static GraphicDevice panel; -static struct fb_videomode *gmode; +static struct fb_videomode const *gmode; static uint8_t gdisp; static uint32_t gpixfmt; @@ -503,7 +503,7 @@ static struct fb_info *mxcfb_init_fbinfo(void) * @return Appropriate error code to the kernel common code */ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, - struct fb_videomode *mode) + struct fb_videomode const *mode) { struct fb_info *fbi; struct mxcfb_info *mxcfbi; @@ -619,7 +619,9 @@ void video_set_lut(unsigned int index, /* color number */ return; } -int ipuv3_fb_init(struct fb_videomode *mode, uint8_t disp, uint32_t pixfmt) +int ipuv3_fb_init(struct fb_videomode const *mode, + uint8_t disp, + uint32_t pixfmt) { gmode = mode; gdisp = disp; |