aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_nv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sata_nv.c')
-rw-r--r--drivers/scsi/sata_nv.c181
1 files changed, 62 insertions, 119 deletions
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index e5b20c6afc18..f77bf183dfab 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;
@@ -332,36 +304,23 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance,
332 304
333static 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)
334{ 306{
335 struct ata_host_set *host_set = ap->host_set;
336 struct nv_host *host = host_set->private_data;
337
338 if (sc_reg > SCR_CONTROL) 307 if (sc_reg > SCR_CONTROL)
339 return 0xffffffffU; 308 return 0xffffffffU;
340 309
341 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) 310 return ioread32((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
342 return readl((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
343 else
344 return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
345} 311}
346 312
347static 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)
348{ 314{
349 struct ata_host_set *host_set = ap->host_set;
350 struct nv_host *host = host_set->private_data;
351
352 if (sc_reg > SCR_CONTROL) 315 if (sc_reg > SCR_CONTROL)
353 return; 316 return;
354 317
355 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) 318 iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
356 writel(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
357 else
358 outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
359} 319}
360 320
361static void nv_host_stop (struct ata_host_set *host_set) 321static void nv_host_stop (struct ata_host_set *host_set)
362{ 322{
363 struct nv_host *host = host_set->private_data; 323 struct nv_host *host = host_set->private_data;
364 struct pci_dev *pdev = to_pci_dev(host_set->dev);
365 324
366 // Disable hotplug event interrupts. 325 // Disable hotplug event interrupts.
367 if (host->host_desc->disable_hotplug) 326 if (host->host_desc->disable_hotplug)
@@ -369,8 +328,7 @@ static void nv_host_stop (struct ata_host_set *host_set)
369 328
370 kfree(host); 329 kfree(host);
371 330
372 if (host_set->mmio_base) 331 ata_pci_host_stop(host_set);
373 pci_iounmap(pdev, host_set->mmio_base);
374} 332}
375 333
376static 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)
@@ -382,6 +340,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
382 int pci_dev_busy = 0; 340 int pci_dev_busy = 0;
383 int rc; 341 int rc;
384 u32 bar; 342 u32 bar;
343 unsigned long base;
385 344
386 // 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
387 // (NVIDIA SATA controllers will always have six bars). Otherwise, 346 // (NVIDIA SATA controllers will always have six bars). Otherwise,
@@ -426,31 +385,16 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
426 385
427 probe_ent->private_data = host; 386 probe_ent->private_data = host;
428 387
429 if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM) 388 probe_ent->mmio_base = pci_iomap(pdev, 5, 0);
430 host->host_flags |= NV_HOST_FLAGS_SCR_MMIO; 389 if (!probe_ent->mmio_base) {
431 390 rc = -EIO;
432 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) { 391 goto err_out_free_host;
433 unsigned long base; 392 }
434
435 probe_ent->mmio_base = pci_iomap(pdev, 5, 0);
436 if (probe_ent->mmio_base == NULL) {
437 rc = -EIO;
438 goto err_out_free_host;
439 }
440
441 base = (unsigned long)probe_ent->mmio_base;
442 393
443 probe_ent->port[0].scr_addr = 394 base = (unsigned long)probe_ent->mmio_base;
444 base + NV_PORT0_SCR_REG_OFFSET;
445 probe_ent->port[1].scr_addr =
446 base + NV_PORT1_SCR_REG_OFFSET;
447 } else {
448 395
449 probe_ent->port[0].scr_addr = 396 probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
450 pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET; 397 probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
451 probe_ent->port[1].scr_addr =
452 pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET;
453 }
454 398
455 pci_set_master(pdev); 399 pci_set_master(pdev);
456 400
@@ -467,8 +411,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
467 return 0; 411 return 0;
468 412
469err_out_iounmap: 413err_out_iounmap:
470 if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) 414 pci_iounmap(pdev, probe_ent->mmio_base);
471 pci_iounmap(pdev, probe_ent->mmio_base);
472err_out_free_host: 415err_out_free_host:
473 kfree(host); 416 kfree(host);
474err_out_free_ent: 417err_out_free_ent: