X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fata%2Fpata_legacy.c;h=dae85aa12e32e60fd6269c0b9881c1e715638b59;hb=55dba3120fbcbea6800f9a18503d25f73212a347;hp=86fbcd6a742b5dbb486b471806e496ef8ebf6712;hpb=8b966dddc29899008fb178a533263afa8d1ad849;p=pandora-kernel.git diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 86fbcd6a742b..dae85aa12e32 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -64,7 +64,7 @@ #include #define DRV_NAME "pata_legacy" -#define DRV_VERSION "0.5.4" +#define DRV_VERSION "0.5.5" #define NR_HOST 6 @@ -96,7 +96,7 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ /** * legacy_set_mode - mode setting - * @ap: IDE interface + * @link: IDE link * @unused: Device that failed when error is returned * * Use a non standard set_mode function. We don't want to be tuned. @@ -107,12 +107,11 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ * expand on this as per hdparm in the base kernel. */ -static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) +static int legacy_set_mode(struct ata_link *link, struct ata_device **unused) { - int i; + struct ata_device *dev; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; + ata_link_for_each_dev(dev, link) { if (ata_dev_enabled(dev)) { ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); dev->pio_mode = XFER_PIO_0; @@ -151,7 +150,6 @@ static struct scsi_host_template legacy_sht = { */ static struct ata_port_operations simple_port_ops = { - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -162,6 +160,7 @@ static struct ata_port_operations simple_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -171,7 +170,6 @@ static struct ata_port_operations simple_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -179,12 +177,12 @@ static struct ata_port_operations simple_port_ops = { static struct ata_port_operations legacy_port_ops = { .set_mode = legacy_set_mode, - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .cable_detect = ata_cable_40wire, .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, @@ -199,7 +197,6 @@ static struct ata_port_operations legacy_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -252,13 +249,14 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) } -static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) +static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = adev->ap; - int slop = buflen & 3; - unsigned long flags; - if (ata_id_has_dword_io(adev->id)) { + struct ata_port *ap = dev->link->ap; + int slop = buflen & 3; + unsigned long flags; + local_irq_save(flags); /* Perform the 32bit I/O synchronization sequence */ @@ -267,34 +265,32 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig ioread8(ap->ioaddr.nsect_addr); /* Now the data */ - - if (write_data) - iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); - else + if (rw == READ) ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + else + iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { u32 pad; - if (write_data) { - memcpy(&pad, buf + buflen - slop, slop); - pad = le32_to_cpu(pad); - iowrite32(pad, ap->ioaddr.data_addr); - } else { - pad = ioread32(ap->ioaddr.data_addr); - pad = cpu_to_le16(pad); + if (rw == READ) { + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); + } else { + memcpy(&pad, buf + buflen - slop, slop); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } + buflen += 4 - slop; } local_irq_restore(flags); - } - else - ata_data_xfer_noirq(adev, buf, buflen, write_data); + } else + buflen = ata_data_xfer_noirq(dev, buf, buflen, rw); + + return buflen; } static struct ata_port_operations pdc20230_port_ops = { .set_piomode = pdc20230_set_piomode, - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -305,6 +301,7 @@ static struct ata_port_operations pdc20230_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -314,7 +311,6 @@ static struct ata_port_operations pdc20230_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -349,7 +345,6 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) static struct ata_port_operations ht6560a_port_ops = { .set_piomode = ht6560a_set_piomode, - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -360,6 +355,7 @@ static struct ata_port_operations ht6560a_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -369,7 +365,6 @@ static struct ata_port_operations ht6560a_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -415,7 +410,6 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) static struct ata_port_operations ht6560b_port_ops = { .set_piomode = ht6560b_set_piomode, - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -426,6 +420,7 @@ static struct ata_port_operations ht6560b_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -435,7 +430,6 @@ static struct ata_port_operations ht6560b_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -536,7 +530,6 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev static struct ata_port_operations opti82c611a_port_ops = { .set_piomode = opti82c611a_set_piomode, - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -547,6 +540,7 @@ static struct ata_port_operations opti82c611a_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -556,7 +550,6 @@ static struct ata_port_operations opti82c611a_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -669,7 +662,6 @@ static unsigned int opti82c46x_qc_issue_prot(struct ata_queued_cmd *qc) static struct ata_port_operations opti82c46x_port_ops = { .set_piomode = opti82c46x_set_piomode, - .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -680,6 +672,7 @@ static struct ata_port_operations opti82c46x_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, .qc_prep = ata_qc_prep, .qc_issue = opti82c46x_qc_issue_prot, @@ -689,7 +682,6 @@ static struct ata_port_operations opti82c46x_port_ops = { .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, .port_start = ata_port_start, }; @@ -709,7 +701,8 @@ static struct ata_port_operations opti82c46x_port_ops = { static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq) { struct legacy_data *ld = &legacy_data[nr_legacy_host]; - struct ata_probe_ent ae; + struct ata_host *host; + struct ata_port *ap; struct platform_device *pdev; struct ata_port_operations *ops = &legacy_port_ops; void __iomem *io_addr, *ctrl_addr; @@ -791,24 +784,25 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl if (ops == &legacy_port_ops && (autospeed & mask)) ops = &simple_port_ops; - memset(&ae, 0, sizeof(struct ata_probe_ent)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &pdev->dev; - ae.port_ops = ops; - ae.sht = &legacy_sht; - ae.n_ports = 1; - ae.pio_mask = pio_modes; - ae.irq = irq; - ae.irq_flags = 0; - ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy; - ae.port[0].cmd_addr = io_addr; - ae.port[0].altstatus_addr = ctrl_addr; - ae.port[0].ctl_addr = ctrl_addr; - ata_std_ports(&ae.port[0]); - ae.private_data = ld; - - ret = -ENODEV; - if (!ata_device_add(&ae)) + ret = -ENOMEM; + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + goto fail; + ap = host->ports[0]; + + ap->ops = ops; + ap->pio_mask = pio_modes; + ap->flags |= ATA_FLAG_SLAVE_POSS | iordy; + ap->ioaddr.cmd_addr = io_addr; + ap->ioaddr.altstatus_addr = ctrl_addr; + ap->ioaddr.ctl_addr = ctrl_addr; + ata_std_ports(&ap->ioaddr); + ap->private_data = ld; + + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, ctrl); + + ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht); + if (ret) goto fail; legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);