aboutsummaryrefslogtreecommitdiff
path: root/drivers/ata/sata_svw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_svw.c')
-rw-r--r--drivers/ata/sata_svw.c124
1 files changed, 73 insertions, 51 deletions
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 69f651e0bc9..16aa6839aa5 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -45,6 +45,8 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi.h>
#include <linux/libata.h>
#ifdef CONFIG_PPC_OF
@@ -59,6 +61,7 @@ enum {
/* ap->flags bits */
K2_FLAG_SATA_8_PORTS = (1 << 24),
K2_FLAG_NO_ATAPI_DMA = (1 << 25),
+ K2_FLAG_BAR_POS_3 = (1 << 26),
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
@@ -88,8 +91,10 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
- board_svw4 = 0,
- board_svw8 = 1,
+ chip_svw4 = 0,
+ chip_svw8 = 1,
+ chip_svw42 = 2, /* bar 3 */
+ chip_svw43 = 3, /* bar 5 */
};
static u8 k2_stat_check_status(struct ata_port *ap);
@@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap);
static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
{
+ u8 cmnd = qc->scsicmd->cmnd[0];
+
if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
return -1; /* ATAPI DMA not supported */
+ else {
+ switch (cmnd) {
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
+ return 0;
+
+ default:
+ return -1;
+ }
- return 0;
+ }
}
static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -213,7 +233,7 @@ static void k2_bmdma_setup_mmio(struct ata_queued_cmd *qc)
/* issue r/w command if this is not a ATA DMA command*/
if (qc->tf.protocol != ATA_PROT_DMA)
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
/**
@@ -249,7 +269,7 @@ static void k2_bmdma_start_mmio(struct ata_queued_cmd *qc)
and the start command. */
/* issue r/w command if the access is to ATA*/
if (qc->tf.protocol == ATA_PROT_DMA)
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
@@ -307,54 +327,27 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
static struct scsi_host_template k2_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
+ ATA_BMDMA_SHT(DRV_NAME),
#ifdef CONFIG_PPC_OF
.proc_info = k2_sata_proc_info,
#endif
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations k2_sata_ops = {
- .tf_load = k2_sata_tf_load,
- .tf_read = k2_sata_tf_read,
- .check_status = k2_stat_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
+static struct ata_port_operations k2_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .sff_tf_load = k2_sata_tf_load,
+ .sff_tf_read = k2_sata_tf_read,
+ .sff_check_status = k2_stat_check_status,
.check_atapi_dma = k2_sata_check_atapi_dma,
.bmdma_setup = k2_bmdma_setup_mmio,
.bmdma_start = k2_bmdma_start_mmio,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
.scr_read = k2_sata_scr_read,
.scr_write = k2_sata_scr_write,
- .port_start = ata_port_start,
};
static const struct ata_port_info k2_port_info[] = {
- /* board_svw4 */
+ /* chip_svw4 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
@@ -363,7 +356,7 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
- /* board_svw8 */
+ /* chip_svw8 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
@@ -373,6 +366,24 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
+ /* chip_svw42 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &k2_sata_ops,
+ },
+ /* chip_svw43 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &k2_sata_ops,
+ },
};
static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
@@ -402,7 +413,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
{ &k2_port_info[ent->driver_data], NULL };
struct ata_host *host;
void __iomem *mmio_base;
- int n_ports, i, rc;
+ int n_ports, i, rc, bar_pos;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -416,6 +427,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
if (!host)
return -ENOMEM;
+ bar_pos = 5;
+ if (ppi[0]->flags & K2_FLAG_BAR_POS_3)
+ bar_pos = 3;
/*
* If this driver happens to only be useful on Apple's K2, then
* we should check that here as it has a normal Serverworks ID
@@ -428,17 +442,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
* Check if we have resources mapped at all (second function may
* have been disabled by firmware)
*/
- if (pci_resource_len(pdev, 5) == 0)
+ if (pci_resource_len(pdev, bar_pos) == 0) {
+ /* In IDE mode we need to pin the device to ensure that
+ pcim_release does not clear the busmaster bit in config
+ space, clearing causes busmaster DMA to fail on
+ ports 3 & 4 */
+ pcim_pin_device(pdev);
return -ENODEV;
+ }
/* Request and iomap PCI regions */
- rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
host->iomap = pcim_iomap_table(pdev);
- mmio_base = host->iomap[5];
+ mmio_base = host->iomap[bar_pos];
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
@@ -472,8 +492,8 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
- &k2_sata_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &k2_sata_sht);
}
/* 0x240 is device ID for Apple K2 device
@@ -483,11 +503,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
* controller
* */
static const struct pci_device_id k2_sata_pci_tbl[] = {
- { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
- { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw8 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 },
{ }
};