Commit baaa7805 authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: system recognizes sda1

dma_sync_sg_for_[cpu,device] were added. Driver crashes on reading large
block of data.
parent 61fe8442
...@@ -134,6 +134,9 @@ address must be aligned to a 128-byte cache line, indicated by bits 06:00 being ...@@ -134,6 +134,9 @@ address must be aligned to a 128-byte cache line, indicated by bits 06:00 being
//libahci_debug_saxigp1_save(ap, 0x3000); //libahci_debug_saxigp1_save(ap, 0x3000);
//libahci_debug_saxigp1_save(ap, 0x3000); //libahci_debug_saxigp1_save(ap, 0x3000);
dev_info(dev, "flags (ATA_FLAG_xxx): %u", ap->flags);
dev_info(dev, "pflags (ATA_PFLAG_xxx): %u", ap->pflags);
dev_info(dev, "ahci_elphel.c: Calling ahci_port_resume()"); dev_info(dev, "ahci_elphel.c: Calling ahci_port_resume()");
return ahci_port_resume(ap); return ahci_port_resume(ap);
} }
...@@ -222,7 +225,6 @@ static int elphel_drv_probe(struct platform_device *pdev) ...@@ -222,7 +225,6 @@ static int elphel_drv_probe(struct platform_device *pdev)
//printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr); //printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr);
printk(KERN_DEBUG "======"); printk(KERN_DEBUG "======");
ret = ahci_platform_init_host(pdev, hpriv, &ahci_elphel_port_info, ret = ahci_platform_init_host(pdev, hpriv, &ahci_elphel_port_info,
&ahci_platform_sht); &ahci_platform_sht);
if (ret) { if (ret) {
...@@ -248,12 +250,28 @@ static unsigned int elphel_read_id(struct ata_device *dev, struct ata_taskfile * ...@@ -248,12 +250,28 @@ static unsigned int elphel_read_id(struct ata_device *dev, struct ata_taskfile *
{ {
u32 err_mask; u32 err_mask;
struct device *d = &dev->tdev; struct device *d = &dev->tdev;
int i, len;
char *msg_str;
err_mask = ata_do_dev_read_id(dev, tf, id); err_mask = ata_do_dev_read_id(dev, tf, id);
if (err_mask) if (err_mask)
return err_mask; return err_mask;
dev_info(d, "elphel_read_id(): issue identify command finished"); dev_info(d, "elphel_read_id(): issue identify command finished\n");
/*dev_info(d, "dump IDENTIFY:\n");
msg_str = kzalloc(PAGE_SIZE, GFP_KERNEL);
if (!msg_str)
return 0;
len = 0;
for (i = 0; i < ATA_ID_WORDS; i++) {
if ((i % 16) == 0 && i != 0) {
dev_info(d, "%s\n", msg_str);
len = 0;
}
len += snprintf(msg_str + len, PAGE_SIZE - len, "0x%04x ", id[i]);
}
// print last string
dev_info(d, "%s\n", msg_str);*/
return 0; return 0;
} }
...@@ -265,6 +283,7 @@ static struct ata_port_operations ahci_elphel_ops = { ...@@ -265,6 +283,7 @@ static struct ata_port_operations ahci_elphel_ops = {
}; };
static const struct ata_port_info ahci_elphel_port_info = { static const struct ata_port_info ahci_elphel_port_info = {
AHCI_HFLAGS(AHCI_HFLAG_NO_NCQ),
.flags = AHCI_FLAG_COMMON, .flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
...@@ -273,6 +292,11 @@ static const struct ata_port_info ahci_elphel_port_info = { ...@@ -273,6 +292,11 @@ static const struct ata_port_info ahci_elphel_port_info = {
static struct scsi_host_template ahci_platform_sht = { static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT(DRV_NAME), AHCI_SHT(DRV_NAME),
.can_queue = 1,
.sg_tablesize = AHCI_MAX_SG,
.dma_boundary = AHCI_DMA_BOUNDARY,
.shost_attrs = ahci_shost_attrs,
.sdev_attrs = ahci_sdev_attrs,
}; };
static const struct of_device_id ahci_elphel_of_match[] = { static const struct of_device_id ahci_elphel_of_match[] = {
......
...@@ -1493,14 +1493,14 @@ void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, ...@@ -1493,14 +1493,14 @@ void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
pp->cmd_slot[tag].tbl_addr = cpu_to_le32((cmd_tbl_dma & 0xffffffff)); // All data correct pp->cmd_slot[tag].tbl_addr = cpu_to_le32((cmd_tbl_dma & 0xffffffff)); // All data correct
pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16);
/*
if (msg_str != NULL) { if (msg_str != NULL) {
len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\tfill command slot %u: DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x, DW3 = 0x%08x", len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\tfill command slot %u: DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x, DW3 = 0x%08x",
tag, pp->cmd_slot[tag].opts, pp->cmd_slot[tag].status, pp->cmd_slot[tag].tbl_addr, pp->cmd_slot[tag].tbl_addr_hi); tag, pp->cmd_slot[tag].opts, pp->cmd_slot[tag].status, pp->cmd_slot[tag].tbl_addr, pp->cmd_slot[tag].tbl_addr_hi);
libahci_debug_event(NULL, msg_str, len); libahci_debug_event(NULL, msg_str, len);
kfree(msg_str); kfree(msg_str);
} }
*/
} }
EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot); EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot);
...@@ -1965,7 +1965,9 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) ...@@ -1965,7 +1965,9 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
u32 elhel_dbg_buf[128]; u32 elhel_dbg_buf[128];
int elphel_i; int elphel_i;
/* // elphel test: set tag = 0, change to qc->tag in functions below
//unsigned int tag = 0;
int len; int len;
char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL); char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
if (msg_str != NULL) { if (msg_str != NULL) {
...@@ -1973,7 +1975,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) ...@@ -1973,7 +1975,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
libahci_debug_event(ap, msg_str, len); libahci_debug_event(ap, msg_str, len);
kfree(msg_str); kfree(msg_str);
} }
*/
/* /*
* Fill in command table information. First, the header, * Fill in command table information. First, the header,
* a SATA Register - Host to Device command FIS. * a SATA Register - Host to Device command FIS.
...@@ -1985,6 +1987,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) ...@@ -1985,6 +1987,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
// dma_sync_single_for_cpu(qc->dev, pp->cmd_tbl_dma - 4096, AHCI_CMD_TBL_AR_SZ + 4096, DMA_TO_DEVICE); // dma_sync_single_for_cpu(qc->dev, pp->cmd_tbl_dma - 4096, AHCI_CMD_TBL_AR_SZ + 4096, DMA_TO_DEVICE);
dma_sync_single_for_cpu(qc->dev, pp->cmd_tbl_dma, AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE); dma_sync_single_for_cpu(qc->dev, pp->cmd_tbl_dma, AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE);
cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
//cmd_tbl = pp->cmd_tbl + tag * AHCI_CMD_TBL_SZ;
// elphel_dbg_ptr = (u32*) cmd_tbl; // elphel_dbg_ptr = (u32*) cmd_tbl;
...@@ -2017,12 +2020,21 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) ...@@ -2017,12 +2020,21 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
// libahci_debug_dump_region(ap, (const u32 *)(cmd_tbl + AHCI_CMD_TBL_CDB), 4, "\tthis is ATAPI command, dump ACMD region: "); // libahci_debug_dump_region(ap, (const u32 *)(cmd_tbl + AHCI_CMD_TBL_CDB), 4, "\tthis is ATAPI command, dump ACMD region: ");
} }
// libahci_debug_dump_region(ap, (const u32 *)cmd_tbl, cmd_fis_len, "\twrite H2D register FIS; dump: "); libahci_debug_dump_region(ap, (const u32 *)cmd_tbl, cmd_fis_len, "\twrite H2D register FIS; dump: ");
n_elem = 0; n_elem = 0;
if (qc->flags & ATA_QCFLAG_DMAMAP) if (qc->flags & ATA_QCFLAG_DMAMAP) {
n_elem = ahci_fill_sg(qc, cmd_tbl); n_elem = ahci_fill_sg(qc, cmd_tbl);
if (qc->dma_dir == DMA_TO_DEVICE) {
dev_info(&qc->dev->tdev, "%s: dma_sync_sg_for_device, qc->dma_dir: %d", __func__, qc->dma_dir);
dma_sync_sg_for_device(&qc->dev->tdev, qc->sg, qc->n_elem, qc->dma_dir);
} else if (qc->dma_dir == DMA_FROM_DEVICE) {
dev_info(&qc->dev->tdev, "%s: dma_sync_sg_for_cpu, qc->dma_dir: %d", __func__, qc->dma_dir);
dma_sync_sg_for_cpu(&qc->dev->tdev, qc->sg, qc->n_elem, qc->dma_dir);
}
}
/* /*
* Fill in command slot information. * Fill in command slot information.
*/ */
...@@ -2033,6 +2045,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) ...@@ -2033,6 +2045,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH;
ahci_fill_cmd_slot(pp, qc->tag, opts); ahci_fill_cmd_slot(pp, qc->tag, opts);
//ahci_fill_cmd_slot(pp, tag, opts);
// Elphel move to ahci_elphel.c. See if the SG dma should also be handed to dma here // Elphel move to ahci_elphel.c. See if the SG dma should also be handed to dma here
dma_sync_single_for_device(qc->dev, pp->cmd_tbl_dma, AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE); dma_sync_single_for_device(qc->dev, pp->cmd_tbl_dma, AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE);
...@@ -2427,6 +2440,8 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) ...@@ -2427,6 +2440,8 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
void __iomem *port_mmio = ahci_port_base(ap); void __iomem *port_mmio = ahci_port_base(ap);
struct ahci_port_priv *pp = ap->private_data; struct ahci_port_priv *pp = ap->private_data;
// elphel test: set tag = 0
//unsigned int tag = 0;
int len; int len;
char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL); char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
if (msg_str != NULL) { if (msg_str != NULL) {
...@@ -2443,10 +2458,12 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) ...@@ -2443,10 +2458,12 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
if (qc->tf.protocol == ATA_PROT_NCQ) { if (qc->tf.protocol == ATA_PROT_NCQ) {
if (msg_str != NULL) { if (msg_str != NULL) {
len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\twrite port %u register PxSACT, value: 0x%08x", ap->port_no, (1 << qc->tag)); len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\twrite port %u register PxSACT, value: 0x%08x", ap->port_no, (1 << qc->tag));
//len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\twrite port %u register PxSACT, value: 0x%08x", ap->port_no, (1 << tag));
libahci_debug_event(ap, msg_str, len); libahci_debug_event(ap, msg_str, len);
} }
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
//writel(1 << tag, port_mmio + PORT_SCR_ACT);
} }
if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) { if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) {
...@@ -2461,9 +2478,8 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) ...@@ -2461,9 +2478,8 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
pp->fbs_last_dev = qc->dev->link->pmp; pp->fbs_last_dev = qc->dev->link->pmp;
} }
//libahci_debug_wait_flag();
writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE);
//writel(1 << tag, port_mmio + PORT_CMD_ISSUE);
ahci_sw_activity(qc->dev->link); ahci_sw_activity(qc->dev->link);
......
...@@ -698,7 +698,9 @@ static ssize_t libahci_debug_load(struct file *f, const char __user *buff, size_ ...@@ -698,7 +698,9 @@ static ssize_t libahci_debug_load(struct file *f, const char __user *buff, size_
*/ */
void libahci_debug_wait_flag(void) void libahci_debug_wait_flag(void)
{ {
char *msg_str = "waiting for flag to be written to debugfs";
printk(KERN_DEBUG "%s Waiting for flag to be written to debugfs", MARKER); printk(KERN_DEBUG "%s Waiting for flag to be written to debugfs", MARKER);
libahci_debug_event(NULL, msg_str, sizeof(*msg_str));
while (load_flag == false) { while (load_flag == false) {
/*set_current_state(TASK_INTERRUPTIBLE); /*set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(100));*/ schedule_timeout(msecs_to_jiffies(100));*/
......
...@@ -4893,6 +4893,16 @@ void ata_qc_complete(struct ata_queued_cmd *qc) ...@@ -4893,6 +4893,16 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
* not synchronize with interrupt handler. Only PIO task is * not synchronize with interrupt handler. Only PIO task is
* taken care of. * taken care of.
*/ */
dev_info(&qc->dev->tdev, "%s: qc->dma_dir: %d", __func__, qc->dma_dir);
if (qc->dma_dir == DMA_TO_DEVICE) {
dev_info(&qc->dev->tdev, "%s: dma_sync_sg_for_device, qc->dma_dir: %d", __func__, qc->dma_dir);
dma_sync_sg_for_device(&qc->dev->tdev, qc->sg, qc->n_elem, qc->dma_dir);
} else if (qc->dma_dir == DMA_FROM_DEVICE) {
dev_info(&qc->dev->tdev, "%s: dma_sync_sg_for_cpu, qc->dma_dir: %d", __func__, qc->dma_dir);
dma_sync_sg_for_cpu(&qc->dev->tdev, qc->sg, qc->n_elem, qc->dma_dir);
}
if (ap->ops->error_handler) { if (ap->ops->error_handler) {
struct ata_device *dev = qc->dev; struct ata_device *dev = qc->dev;
struct ata_eh_info *ehi = &dev->link->eh_info; struct ata_eh_info *ehi = &dev->link->eh_info;
......
...@@ -2556,6 +2556,10 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -2556,6 +2556,10 @@ static void ata_eh_link_report(struct ata_link *link)
res->device, qc->err_mask, ata_err_string(qc->err_mask), res->device, qc->err_mask, ata_err_string(qc->err_mask),
qc->err_mask & AC_ERR_NCQ ? " <F>" : ""); qc->err_mask & AC_ERR_NCQ ? " <F>" : "");
// elphel test: crash driver here to stop its execution and preserve memory state
//u32 *tmp_str = NULL;
//ata_dev_err(qc->dev, "test: %u", *tmp_str);
#ifdef CONFIG_ATA_VERBOSE_ERROR #ifdef CONFIG_ATA_VERBOSE_ERROR
if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
ATA_ERR)) { ATA_ERR)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment