aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAnantha Subramanyam <ananth@broadcom.com>2008-02-28 18:58:35 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-28 19:02:29 -0500
commit931506d3b2208362efc678ee863ee42a90755e89 (patch)
tree5ece2059132168668e863590562a415e67c664fe /drivers/ata
parent7704a8b6fc4a8f51599eb2af4dcf1e2ac9c7e576 (diff)
sata_svw: Add support for HT1100 SATA controller
This patch adds support (including ATAPI DMA) for HT1100 (aka BCM11000) SATA controller. Signed-off-by: Anantha Subramanyam <ananth@broadcom.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_svw.c77
1 files changed, 63 insertions, 14 deletions
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 69f651e0bc98..840d1c4a7850 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -45,6 +45,8 @@
45#include <linux/interrupt.h> 45#include <linux/interrupt.h>
46#include <linux/device.h> 46#include <linux/device.h>
47#include <scsi/scsi_host.h> 47#include <scsi/scsi_host.h>
48#include <scsi/scsi_cmnd.h>
49#include <scsi/scsi.h>
48#include <linux/libata.h> 50#include <linux/libata.h>
49 51
50#ifdef CONFIG_PPC_OF 52#ifdef CONFIG_PPC_OF
@@ -59,6 +61,7 @@ enum {
59 /* ap->flags bits */ 61 /* ap->flags bits */
60 K2_FLAG_SATA_8_PORTS = (1 << 24), 62 K2_FLAG_SATA_8_PORTS = (1 << 24),
61 K2_FLAG_NO_ATAPI_DMA = (1 << 25), 63 K2_FLAG_NO_ATAPI_DMA = (1 << 25),
64 K2_FLAG_BAR_POS_3 = (1 << 26),
62 65
63 /* Taskfile registers offsets */ 66 /* Taskfile registers offsets */
64 K2_SATA_TF_CMD_OFFSET = 0x00, 67 K2_SATA_TF_CMD_OFFSET = 0x00,
@@ -88,8 +91,10 @@ enum {
88 /* Port stride */ 91 /* Port stride */
89 K2_SATA_PORT_OFFSET = 0x100, 92 K2_SATA_PORT_OFFSET = 0x100,
90 93
91 board_svw4 = 0, 94 chip_svw4 = 0,
92 board_svw8 = 1, 95 chip_svw8 = 1,
96 chip_svw42 = 2, /* bar 3 */
97 chip_svw43 = 3, /* bar 5 */
93}; 98};
94 99
95static u8 k2_stat_check_status(struct ata_port *ap); 100static u8 k2_stat_check_status(struct ata_port *ap);
@@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap);
97 102
98static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) 103static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
99{ 104{
105 u8 cmnd = qc->scsicmd->cmnd[0];
106
100 if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) 107 if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
101 return -1; /* ATAPI DMA not supported */ 108 return -1; /* ATAPI DMA not supported */
109 else {
110 switch (cmnd) {
111 case READ_10:
112 case READ_12:
113 case READ_16:
114 case WRITE_10:
115 case WRITE_12:
116 case WRITE_16:
117 return 0;
118
119 default:
120 return -1;
121 }
102 122
103 return 0; 123 }
104} 124}
105 125
106static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) 126static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = {
354}; 374};
355 375
356static const struct ata_port_info k2_port_info[] = { 376static const struct ata_port_info k2_port_info[] = {
357 /* board_svw4 */ 377 /* chip_svw4 */
358 { 378 {
359 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 379 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
360 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, 380 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
@@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = {
363 .udma_mask = ATA_UDMA6, 383 .udma_mask = ATA_UDMA6,
364 .port_ops = &k2_sata_ops, 384 .port_ops = &k2_sata_ops,
365 }, 385 },
366 /* board_svw8 */ 386 /* chip_svw8 */
367 { 387 {
368 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 388 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
369 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | 389 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
@@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = {
373 .udma_mask = ATA_UDMA6, 393 .udma_mask = ATA_UDMA6,
374 .port_ops = &k2_sata_ops, 394 .port_ops = &k2_sata_ops,
375 }, 395 },
396 /* chip_svw42 */
397 {
398 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
399 ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
400 .pio_mask = 0x1f,
401 .mwdma_mask = 0x07,
402 .udma_mask = ATA_UDMA6,
403 .port_ops = &k2_sata_ops,
404 },
405 /* chip_svw43 */
406 {
407 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
408 ATA_FLAG_MMIO,
409 .pio_mask = 0x1f,
410 .mwdma_mask = 0x07,
411 .udma_mask = ATA_UDMA6,
412 .port_ops = &k2_sata_ops,
413 },
376}; 414};
377 415
378static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) 416static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
@@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
402 { &k2_port_info[ent->driver_data], NULL }; 440 { &k2_port_info[ent->driver_data], NULL };
403 struct ata_host *host; 441 struct ata_host *host;
404 void __iomem *mmio_base; 442 void __iomem *mmio_base;
405 int n_ports, i, rc; 443 int n_ports, i, rc, bar_pos;
406 444
407 if (!printed_version++) 445 if (!printed_version++)
408 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); 446 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
416 if (!host) 454 if (!host)
417 return -ENOMEM; 455 return -ENOMEM;
418 456
457 bar_pos = 5;
458 if (ppi[0]->flags & K2_FLAG_BAR_POS_3)
459 bar_pos = 3;
419 /* 460 /*
420 * If this driver happens to only be useful on Apple's K2, then 461 * If this driver happens to only be useful on Apple's K2, then
421 * we should check that here as it has a normal Serverworks ID 462 * we should check that here as it has a normal Serverworks ID
@@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
428 * Check if we have resources mapped at all (second function may 469 * Check if we have resources mapped at all (second function may
429 * have been disabled by firmware) 470 * have been disabled by firmware)
430 */ 471 */
431 if (pci_resource_len(pdev, 5) == 0) 472 if (pci_resource_len(pdev, bar_pos) == 0) {
473 /* In IDE mode we need to pin the device to ensure that
474 pcim_release does not clear the busmaster bit in config
475 space, clearing causes busmaster DMA to fail on
476 ports 3 & 4 */
477 pcim_pin_device(pdev);
432 return -ENODEV; 478 return -ENODEV;
479 }
433 480
434 /* Request and iomap PCI regions */ 481 /* Request and iomap PCI regions */
435 rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); 482 rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
436 if (rc == -EBUSY) 483 if (rc == -EBUSY)
437 pcim_pin_device(pdev); 484 pcim_pin_device(pdev);
438 if (rc) 485 if (rc)
439 return rc; 486 return rc;
440 host->iomap = pcim_iomap_table(pdev); 487 host->iomap = pcim_iomap_table(pdev);
441 mmio_base = host->iomap[5]; 488 mmio_base = host->iomap[bar_pos];
442 489
443 /* different controllers have different number of ports - currently 4 or 8 */ 490 /* different controllers have different number of ports - currently 4 or 8 */
444 /* All ports are on the same function. Multi-function device is no 491 /* All ports are on the same function. Multi-function device is no
@@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
483 * controller 530 * controller
484 * */ 531 * */
485static const struct pci_device_id k2_sata_pci_tbl[] = { 532static const struct pci_device_id k2_sata_pci_tbl[] = {
486 { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, 533 { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
487 { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, 534 { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 },
488 { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, 535 { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 },
489 { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, 536 { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 },
490 { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, 537 { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 },
538 { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
539 { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 },
491 540
492 { } 541 { }
493}; 542};