aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_nv.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-03-24 09:24:04 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-24 09:24:04 -0500
commit11ed56fb7899f9eb9eaef8e5919db1bf08f1b07e (patch)
treeb01421cb139b11065d776ed361a7a12b3a1aecc9 /drivers/scsi/sata_nv.c
parent54da9a3968448681d0ddf193ec90f2480c5cba1c (diff)
parent2cc432eed0491df66e14b578139bba2c75fb3f9a (diff)
Merge branch 'upstream'
Conflicts: drivers/scsi/sata_vsc.c
Diffstat (limited to 'drivers/scsi/sata_nv.c')
-rw-r--r--drivers/scsi/sata_nv.c182
1 files changed, 62 insertions, 120 deletions
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 5168db981dde..8a99c3827426 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -29,34 +29,6 @@
29 * NV-specific details such as register offsets, SATA phy location, 29 * NV-specific details such as register offsets, SATA phy location,
30 * hotplug info, etc. 30 * hotplug info, etc.
31 * 31 *
32 * 0.10
33 * - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB
34 * drive. Also made the check_hotplug() callbacks return whether there
35 * was a hotplug interrupt or not. This was not the source of the
36 * spurious interrupts, but is the right thing to do anyway.
37 *
38 * 0.09
39 * - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
40 *
41 * 0.08
42 * - Added support for MCP51 and MCP55.
43 *
44 * 0.07
45 * - Added support for RAID class code.
46 *
47 * 0.06
48 * - Added generic SATA support by using a pci_device_id that filters on
49 * the IDE storage class code.
50 *
51 * 0.03
52 * - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using
53 * mmio_base, which is only set for the CK804/MCP04 case.
54 *
55 * 0.02
56 * - Added support for CK804 SATA controller.
57 *
58 * 0.01
59 * - Initial revision.
60 */ 32 */
61 33
62#include <linux/config.h> 34#include <linux/config.h>
@@ -74,53 +46,55 @@
74#define DRV_NAME "sata_nv" 46#define DRV_NAME "sata_nv"
75#define DRV_VERSION "0.8" 47#define DRV_VERSION "0.8"
76 48
77#define NV_PORTS 2 49enum {
78#define NV_PIO_MASK 0x1f 50 NV_PORTS = 2,
79#define NV_MWDMA_MASK 0x07 51 NV_PIO_MASK = 0x1f,
80#define NV_UDMA_MASK 0x7f 52 NV_MWDMA_MASK = 0x07,
81#define NV_PORT0_SCR_REG_OFFSET 0x00 53 NV_UDMA_MASK = 0x7f,
82#define NV_PORT1_SCR_REG_OFFSET 0x40 54 NV_PORT0_SCR_REG_OFFSET = 0x00,
83 55 NV_PORT1_SCR_REG_OFFSET = 0x40,
84#define NV_INT_STATUS 0x10 56
85#define NV_INT_STATUS_CK804 0x440 57 NV_INT_STATUS = 0x10,
86#define NV_INT_STATUS_PDEV_INT 0x01 58 NV_INT_STATUS_CK804 = 0x440,
87#define NV_INT_STATUS_PDEV_PM 0x02 59 NV_INT_STATUS_PDEV_INT = 0x01,
88#define NV_INT_STATUS_PDEV_ADDED 0x04 60 NV_INT_STATUS_PDEV_PM = 0x02,
89#define NV_INT_STATUS_PDEV_REMOVED 0x08 61 NV_INT_STATUS_PDEV_ADDED = 0x04,
90#define NV_INT_STATUS_SDEV_INT 0x10 62 NV_INT_STATUS_PDEV_REMOVED = 0x08,
91#define NV_INT_STATUS_SDEV_PM 0x20 63 NV_INT_STATUS_SDEV_INT = 0x10,
92#define NV_INT_STATUS_SDEV_ADDED 0x40 64 NV_INT_STATUS_SDEV_PM = 0x20,
93#define NV_INT_STATUS_SDEV_REMOVED 0x80 65 NV_INT_STATUS_SDEV_ADDED = 0x40,
94#define NV_INT_STATUS_PDEV_HOTPLUG (NV_INT_STATUS_PDEV_ADDED | \ 66 NV_INT_STATUS_SDEV_REMOVED = 0x80,
95 NV_INT_STATUS_PDEV_REMOVED) 67 NV_INT_STATUS_PDEV_HOTPLUG = (NV_INT_STATUS_PDEV_ADDED |
96#define NV_INT_STATUS_SDEV_HOTPLUG (NV_INT_STATUS_SDEV_ADDED | \ 68 NV_INT_STATUS_PDEV_REMOVED),
97 NV_INT_STATUS_SDEV_REMOVED) 69 NV_INT_STATUS_SDEV_HOTPLUG = (NV_INT_STATUS_SDEV_ADDED |
98#define NV_INT_STATUS_HOTPLUG (NV_INT_STATUS_PDEV_HOTPLUG | \ 70 NV_INT_STATUS_SDEV_REMOVED),
99 NV_INT_STATUS_SDEV_HOTPLUG) 71 NV_INT_STATUS_HOTPLUG = (NV_INT_STATUS_PDEV_HOTPLUG |
100 72 NV_INT_STATUS_SDEV_HOTPLUG),
101#define NV_INT_ENABLE 0x11 73
102#define NV_INT_ENABLE_CK804 0x441 74 NV_INT_ENABLE = 0x11,
103#define NV_INT_ENABLE_PDEV_MASK 0x01 75 NV_INT_ENABLE_CK804 = 0x441,
104#define NV_INT_ENABLE_PDEV_PM 0x02 76 NV_INT_ENABLE_PDEV_MASK = 0x01,
105#define NV_INT_ENABLE_PDEV_ADDED 0x04 77 NV_INT_ENABLE_PDEV_PM = 0x02,
106#define NV_INT_ENABLE_PDEV_REMOVED 0x08 78 NV_INT_ENABLE_PDEV_ADDED = 0x04,
107#define NV_INT_ENABLE_SDEV_MASK 0x10 79 NV_INT_ENABLE_PDEV_REMOVED = 0x08,
108#define NV_INT_ENABLE_SDEV_PM 0x20 80 NV_INT_ENABLE_SDEV_MASK = 0x10,
109#define NV_INT_ENABLE_SDEV_ADDED 0x40 81 NV_INT_ENABLE_SDEV_PM = 0x20,
110#define NV_INT_ENABLE_SDEV_REMOVED 0x80 82 NV_INT_ENABLE_SDEV_ADDED = 0x40,
111#define NV_INT_ENABLE_PDEV_HOTPLUG (NV_INT_ENABLE_PDEV_ADDED | \ 83 NV_INT_ENABLE_SDEV_REMOVED = 0x80,
112 NV_INT_ENABLE_PDEV_REMOVED) 84 NV_INT_ENABLE_PDEV_HOTPLUG = (NV_INT_ENABLE_PDEV_ADDED |
113#define NV_INT_ENABLE_SDEV_HOTPLUG (NV_INT_ENABLE_SDEV_ADDED | \ 85 NV_INT_ENABLE_PDEV_REMOVED),
114 NV_INT_ENABLE_SDEV_REMOVED) 86 NV_INT_ENABLE_SDEV_HOTPLUG = (NV_INT_ENABLE_SDEV_ADDED |
115#define NV_INT_ENABLE_HOTPLUG (NV_INT_ENABLE_PDEV_HOTPLUG | \ 87 NV_INT_ENABLE_SDEV_REMOVED),
116 NV_INT_ENABLE_SDEV_HOTPLUG) 88 NV_INT_ENABLE_HOTPLUG = (NV_INT_ENABLE_PDEV_HOTPLUG |
117 89 NV_INT_ENABLE_SDEV_HOTPLUG),
118#define NV_INT_CONFIG 0x12 90
119#define NV_INT_CONFIG_METHD 0x01 // 0 = INT, 1 = SMI 91 NV_INT_CONFIG = 0x12,
120 92 NV_INT_CONFIG_METHD = 0x01, // 0 = INT, 1 = SMI
121// For PCI config register 20 93
122#define NV_MCP_SATA_CFG_20 0x50 94 // For PCI config register 20
123#define NV_MCP_SATA_CFG_20_SATA_SPACE_EN 0x04 95 NV_MCP_SATA_CFG_20 = 0x50,
96 NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04,
97};
124 98
125static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); 99static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
126static irqreturn_t nv_interrupt (int irq, void *dev_instance, 100static irqreturn_t nv_interrupt (int irq, void *dev_instance,
@@ -175,8 +149,6 @@ static const struct pci_device_id nv_pci_tbl[] = {
175 { 0, } /* terminate list */ 149 { 0, } /* terminate list */
176}; 150};
177 151
178#define NV_HOST_FLAGS_SCR_MMIO 0x00000001
179
180struct nv_host_desc 152struct nv_host_desc
181{ 153{
182 enum nv_host_type host_type; 154 enum nv_host_type host_type;
@@ -229,7 +201,6 @@ static struct scsi_host_template nv_sht = {
229 .name = DRV_NAME, 201 .name = DRV_NAME,
230 .ioctl = ata_scsi_ioctl, 202 .ioctl = ata_scsi_ioctl,
231 .queuecommand = ata_scsi_queuecmd, 203 .queuecommand = ata_scsi_queuecmd,
232 .eh_timed_out = ata_scsi_timed_out,
233 .eh_strategy_handler = ata_scsi_error, 204 .eh_strategy_handler = ata_scsi_error,
234 .can_queue = ATA_DEF_QUEUE, 205 .can_queue = ATA_DEF_QUEUE,
235 .this_id = ATA_SHT_THIS_ID, 206 .this_id = ATA_SHT_THIS_ID,
@@ -333,36 +304,23 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance,
333 304
334static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) 305static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
335{ 306{
336 struct ata_host_set *host_set = ap->host_set;
337 struct nv_host *host = host_set->private_data;
338
339 if (sc_reg > SCR_CONTROL) 307 if (sc_reg > SCR_CONTROL)
340 return 0xffffffffU; 308 return 0xffffffffU;
341 309
342 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) 310 return ioread32((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
343 return readl((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
344 else
345 return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
346} 311}
347 312
348static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) 313static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
349{ 314{
350 struct ata_host_set *host_set = ap->host_set;
351 struct nv_host *host = host_set->private_data;
352
353 if (sc_reg > SCR_CONTROL) 315 if (sc_reg > SCR_CONTROL)
354 return; 316 return;
355 317
356 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) 318 iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
357 writel(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
358 else
359 outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
360} 319}
361 320
362static void nv_host_stop (struct ata_host_set *host_set) 321static void nv_host_stop (struct ata_host_set *host_set)
363{ 322{
364 struct nv_host *host = host_set->private_data; 323 struct nv_host *host = host_set->private_data;
365 struct pci_dev *pdev = to_pci_dev(host_set->dev);
366 324
367 // Disable hotplug event interrupts. 325 // Disable hotplug event interrupts.
368 if (host->host_desc->disable_hotplug) 326 if (host->host_desc->disable_hotplug)
@@ -370,8 +328,7 @@ static void nv_host_stop (struct ata_host_set *host_set)
370 328
371 kfree(host); 329 kfree(host);
372 330
373 if (host_set->mmio_base) 331 ata_pci_host_stop(host_set);
374 pci_iounmap(pdev, host_set->mmio_base);
375} 332}
376 333
377static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 334static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -383,6 +340,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
383 int pci_dev_busy = 0; 340 int pci_dev_busy = 0;
384 int rc; 341 int rc;
385 u32 bar; 342 u32 bar;
343 unsigned long base;
386 344
387 // Make sure this is a SATA controller by counting the number of bars 345 // Make sure this is a SATA controller by counting the number of bars
388 // (NVIDIA SATA controllers will always have six bars). Otherwise, 346 // (NVIDIA SATA controllers will always have six bars). Otherwise,
@@ -427,31 +385,16 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
427 385
428 probe_ent->private_data = host; 386 probe_ent->private_data = host;
429 387
430 if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM) 388 probe_ent->mmio_base = pci_iomap(pdev, 5, 0);
431 host->host_flags |= NV_HOST_FLAGS_SCR_MMIO; 389 if (!probe_ent->mmio_base) {
432 390 rc = -EIO;
433 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) { 391 goto err_out_free_host;
434 unsigned long base; 392 }
435
436 probe_ent->mmio_base = pci_iomap(pdev, 5, 0);
437 if (probe_ent->mmio_base == NULL) {
438 rc = -EIO;
439 goto err_out_free_host;
440 }
441
442 base = (unsigned long)probe_ent->mmio_base;
443 393
444 probe_ent->port[0].scr_addr = 394 base = (unsigned long)probe_ent->mmio_base;
445 base + NV_PORT0_SCR_REG_OFFSET;
446 probe_ent->port[1].scr_addr =
447 base + NV_PORT1_SCR_REG_OFFSET;
448 } else {
449 395
450 probe_ent->port[0].scr_addr = 396 probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
451 pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET; 397 probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
452 probe_ent->port[1].scr_addr =
453 pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET;
454 }
455 398
456 pci_set_master(pdev); 399 pci_set_master(pdev);
457 400
@@ -468,8 +411,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
468 return 0; 411 return 0;
469 412
470err_out_iounmap: 413err_out_iounmap:
471 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) 414 pci_iounmap(pdev, probe_ent->mmio_base);
472 pci_iounmap(pdev, probe_ent->mmio_base);
473err_out_free_host: 415err_out_free_host:
474 kfree(host); 416 kfree(host);
475err_out_free_ent: 417err_out_free_ent: