diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-03-24 09:24:04 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-24 09:24:04 -0500 |
commit | 11ed56fb7899f9eb9eaef8e5919db1bf08f1b07e (patch) | |
tree | b01421cb139b11065d776ed361a7a12b3a1aecc9 /drivers/scsi/sata_nv.c | |
parent | 54da9a3968448681d0ddf193ec90f2480c5cba1c (diff) | |
parent | 2cc432eed0491df66e14b578139bba2c75fb3f9a (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.c | 182 |
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 | 49 | enum { |
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 | ||
125 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 99 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
126 | static irqreturn_t nv_interrupt (int irq, void *dev_instance, | 100 | static 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 | |||
180 | struct nv_host_desc | 152 | struct 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 | ||
334 | static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) | 305 | static 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 | ||
348 | static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 313 | static 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 | ||
362 | static void nv_host_stop (struct ata_host_set *host_set) | 321 | static 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 | ||
377 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 334 | static 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 | ||
470 | err_out_iounmap: | 413 | err_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); | ||
473 | err_out_free_host: | 415 | err_out_free_host: |
474 | kfree(host); | 416 | kfree(host); |
475 | err_out_free_ent: | 417 | err_out_free_ent: |