diff options
Diffstat (limited to 'drivers')
97 files changed, 3308 insertions, 2204 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 1aabc81d82f..54e1f38ce30 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -299,76 +299,46 @@ static const struct ata_port_info ahci_port_info[] = { | |||
299 | 299 | ||
300 | static const struct pci_device_id ahci_pci_tbl[] = { | 300 | static const struct pci_device_id ahci_pci_tbl[] = { |
301 | /* Intel */ | 301 | /* Intel */ |
302 | { PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 302 | { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */ |
303 | board_ahci }, /* ICH6 */ | 303 | { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */ |
304 | { PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 304 | { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ |
305 | board_ahci }, /* ICH6M */ | 305 | { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */ |
306 | { PCI_VENDOR_ID_INTEL, 0x27c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 306 | { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */ |
307 | board_ahci }, /* ICH7 */ | 307 | { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */ |
308 | { PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 308 | { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */ |
309 | board_ahci }, /* ICH7M */ | 309 | { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ |
310 | { PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 310 | { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ |
311 | board_ahci }, /* ICH7R */ | 311 | { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ |
312 | { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 312 | { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ |
313 | board_ahci }, /* ULi M5288 */ | 313 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */ |
314 | { PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 314 | { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ |
315 | board_ahci }, /* ESB2 */ | 315 | { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ |
316 | { PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 316 | { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ |
317 | board_ahci }, /* ESB2 */ | ||
318 | { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
319 | board_ahci }, /* ESB2 */ | ||
320 | { PCI_VENDOR_ID_INTEL, 0x27c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
321 | board_ahci }, /* ICH7-M DH */ | ||
322 | { PCI_VENDOR_ID_INTEL, 0x2821, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
323 | board_ahci }, /* ICH8 */ | ||
324 | { PCI_VENDOR_ID_INTEL, 0x2822, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
325 | board_ahci }, /* ICH8 */ | ||
326 | { PCI_VENDOR_ID_INTEL, 0x2824, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
327 | board_ahci }, /* ICH8 */ | ||
328 | { PCI_VENDOR_ID_INTEL, 0x2829, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
329 | board_ahci }, /* ICH8M */ | ||
330 | { PCI_VENDOR_ID_INTEL, 0x282a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
331 | board_ahci }, /* ICH8M */ | ||
332 | 317 | ||
333 | /* JMicron */ | 318 | /* JMicron */ |
334 | { 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 319 | { PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */ |
335 | board_ahci }, /* JMicron JMB360 */ | 320 | { PCI_VDEVICE(JMICRON, 0x2361), board_ahci }, /* JMicron JMB361 */ |
336 | { 0x197b, 0x2361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 321 | { PCI_VDEVICE(JMICRON, 0x2363), board_ahci }, /* JMicron JMB363 */ |
337 | board_ahci }, /* JMicron JMB361 */ | 322 | { PCI_VDEVICE(JMICRON, 0x2365), board_ahci }, /* JMicron JMB365 */ |
338 | { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 323 | { PCI_VDEVICE(JMICRON, 0x2366), board_ahci }, /* JMicron JMB366 */ |
339 | board_ahci }, /* JMicron JMB363 */ | ||
340 | { 0x197b, 0x2365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
341 | board_ahci }, /* JMicron JMB365 */ | ||
342 | { 0x197b, 0x2366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
343 | board_ahci }, /* JMicron JMB366 */ | ||
344 | 324 | ||
345 | /* ATI */ | 325 | /* ATI */ |
346 | { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 326 | { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ |
347 | board_ahci }, /* ATI SB600 non-raid */ | 327 | { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */ |
348 | { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
349 | board_ahci }, /* ATI SB600 raid */ | ||
350 | 328 | ||
351 | /* VIA */ | 329 | /* VIA */ |
352 | { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 330 | { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ |
353 | board_ahci_vt8251 }, /* VIA VT8251 */ | ||
354 | 331 | ||
355 | /* NVIDIA */ | 332 | /* NVIDIA */ |
356 | { PCI_VENDOR_ID_NVIDIA, 0x044c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 333 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ |
357 | board_ahci }, /* MCP65 */ | 334 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ |
358 | { PCI_VENDOR_ID_NVIDIA, 0x044d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 335 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ |
359 | board_ahci }, /* MCP65 */ | 336 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ |
360 | { PCI_VENDOR_ID_NVIDIA, 0x044e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
361 | board_ahci }, /* MCP65 */ | ||
362 | { PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
363 | board_ahci }, /* MCP65 */ | ||
364 | 337 | ||
365 | /* SiS */ | 338 | /* SiS */ |
366 | { PCI_VENDOR_ID_SI, 0x1184, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 339 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ |
367 | board_ahci }, /* SiS 966 */ | 340 | { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ |
368 | { PCI_VENDOR_ID_SI, 0x1185, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 341 | { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ |
369 | board_ahci }, /* SiS 966 */ | ||
370 | { PCI_VENDOR_ID_SI, 0x0186, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
371 | board_ahci }, /* SiS 968 */ | ||
372 | 342 | ||
373 | { } /* terminate list */ | 343 | { } /* terminate list */ |
374 | }; | 344 | }; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b4abd685036..dce65651d85 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2340,7 +2340,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap, | |||
2340 | 2340 | ||
2341 | if (status & ATA_BUSY) | 2341 | if (status & ATA_BUSY) |
2342 | ata_port_printk(ap, KERN_WARNING, | 2342 | ata_port_printk(ap, KERN_WARNING, |
2343 | "port is slow to respond, please be patient\n"); | 2343 | "port is slow to respond, please be patient " |
2344 | "(Status 0x%x)\n", status); | ||
2344 | 2345 | ||
2345 | timeout = timer_start + tmout; | 2346 | timeout = timer_start + tmout; |
2346 | while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { | 2347 | while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { |
@@ -2350,7 +2351,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap, | |||
2350 | 2351 | ||
2351 | if (status & ATA_BUSY) { | 2352 | if (status & ATA_BUSY) { |
2352 | ata_port_printk(ap, KERN_ERR, "port failed to respond " | 2353 | ata_port_printk(ap, KERN_ERR, "port failed to respond " |
2353 | "(%lu secs)\n", tmout / HZ); | 2354 | "(%lu secs, Status 0x%x)\n", |
2355 | tmout / HZ, status); | ||
2354 | return 1; | 2356 | return 1; |
2355 | } | 2357 | } |
2356 | 2358 | ||
@@ -5478,11 +5480,10 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5478 | int irq_line = ent->irq; | 5480 | int irq_line = ent->irq; |
5479 | 5481 | ||
5480 | ap = ata_port_add(ent, host, i); | 5482 | ap = ata_port_add(ent, host, i); |
5483 | host->ports[i] = ap; | ||
5481 | if (!ap) | 5484 | if (!ap) |
5482 | goto err_out; | 5485 | goto err_out; |
5483 | 5486 | ||
5484 | host->ports[i] = ap; | ||
5485 | |||
5486 | /* dummy? */ | 5487 | /* dummy? */ |
5487 | if (ent->dummy_port_mask & (1 << i)) { | 5488 | if (ent->dummy_port_mask & (1 << i)) { |
5488 | ata_port_printk(ap, KERN_INFO, "DUMMY\n"); | 5489 | ata_port_printk(ap, KERN_INFO, "DUMMY\n"); |
@@ -5740,7 +5741,7 @@ void ata_host_remove(struct ata_host *host) | |||
5740 | 5741 | ||
5741 | /** | 5742 | /** |
5742 | * ata_scsi_release - SCSI layer callback hook for host unload | 5743 | * ata_scsi_release - SCSI layer callback hook for host unload |
5743 | * @host: libata host to be unloaded | 5744 | * @shost: libata host to be unloaded |
5744 | * | 5745 | * |
5745 | * Performs all duties necessary to shut down a libata port... | 5746 | * Performs all duties necessary to shut down a libata port... |
5746 | * Kill port kthread, disable port, and release resources. | 5747 | * Kill port kthread, disable port, and release resources. |
@@ -5786,6 +5787,7 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | |||
5786 | probe_ent->mwdma_mask = port->mwdma_mask; | 5787 | probe_ent->mwdma_mask = port->mwdma_mask; |
5787 | probe_ent->udma_mask = port->udma_mask; | 5788 | probe_ent->udma_mask = port->udma_mask; |
5788 | probe_ent->port_ops = port->port_ops; | 5789 | probe_ent->port_ops = port->port_ops; |
5790 | probe_ent->private_data = port->private_data; | ||
5789 | 5791 | ||
5790 | return probe_ent; | 5792 | return probe_ent; |
5791 | } | 5793 | } |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3986ec8741b..b0d0cc41f3e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -889,6 +889,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |||
889 | { | 889 | { |
890 | struct ata_port *ap = ata_shost_to_port(sdev->host); | 890 | struct ata_port *ap = ata_shost_to_port(sdev->host); |
891 | struct ata_device *dev; | 891 | struct ata_device *dev; |
892 | unsigned long flags; | ||
892 | int max_depth; | 893 | int max_depth; |
893 | 894 | ||
894 | if (queue_depth < 1) | 895 | if (queue_depth < 1) |
@@ -904,6 +905,14 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | |||
904 | queue_depth = max_depth; | 905 | queue_depth = max_depth; |
905 | 906 | ||
906 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); | 907 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); |
908 | |||
909 | spin_lock_irqsave(ap->lock, flags); | ||
910 | if (queue_depth > 1) | ||
911 | dev->flags &= ~ATA_DFLAG_NCQ_OFF; | ||
912 | else | ||
913 | dev->flags |= ATA_DFLAG_NCQ_OFF; | ||
914 | spin_unlock_irqrestore(ap->lock, flags); | ||
915 | |||
907 | return queue_depth; | 916 | return queue_depth; |
908 | } | 917 | } |
909 | 918 | ||
@@ -1293,7 +1302,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1293 | */ | 1302 | */ |
1294 | goto nothing_to_do; | 1303 | goto nothing_to_do; |
1295 | 1304 | ||
1296 | if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) { | 1305 | if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | |
1306 | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) { | ||
1297 | /* yay, NCQ */ | 1307 | /* yay, NCQ */ |
1298 | if (!lba_48_ok(block, n_block)) | 1308 | if (!lba_48_ok(block, n_block)) |
1299 | goto out_of_range; | 1309 | goto out_of_range; |
@@ -3174,7 +3184,7 @@ void ata_scsi_dev_rescan(void *data) | |||
3174 | 3184 | ||
3175 | /** | 3185 | /** |
3176 | * ata_sas_port_alloc - Allocate port for a SAS attached SATA device | 3186 | * ata_sas_port_alloc - Allocate port for a SAS attached SATA device |
3177 | * @pdev: PCI device that the scsi device is attached to | 3187 | * @host: ATA host container for all SAS ports |
3178 | * @port_info: Information from low-level host driver | 3188 | * @port_info: Information from low-level host driver |
3179 | * @shost: SCSI host that the scsi device is attached to | 3189 | * @shost: SCSI host that the scsi device is attached to |
3180 | * | 3190 | * |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 08b3a407473..06daaa3736a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -828,7 +828,6 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
828 | 828 | ||
829 | probe_ent->irq = pdev->irq; | 829 | probe_ent->irq = pdev->irq; |
830 | probe_ent->irq_flags = IRQF_SHARED; | 830 | probe_ent->irq_flags = IRQF_SHARED; |
831 | probe_ent->private_data = port[0]->private_data; | ||
832 | 831 | ||
833 | if (ports & ATA_PORT_PRIMARY) { | 832 | if (ports & ATA_PORT_PRIMARY) { |
834 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); | 833 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); |
@@ -878,7 +877,6 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
878 | return NULL; | 877 | return NULL; |
879 | 878 | ||
880 | probe_ent->n_ports = 2; | 879 | probe_ent->n_ports = 2; |
881 | probe_ent->private_data = port[0]->private_data; | ||
882 | 880 | ||
883 | if (port_mask & ATA_PORT_PRIMARY) { | 881 | if (port_mask & ATA_PORT_PRIMARY) { |
884 | probe_ent->irq = ATA_PRIMARY_IRQ; | 882 | probe_ent->irq = ATA_PRIMARY_IRQ; |
@@ -908,6 +906,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
908 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; | 906 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; |
909 | } | 907 | } |
910 | ata_std_ports(&probe_ent->port[1]); | 908 | ata_std_ports(&probe_ent->port[1]); |
909 | |||
910 | /* FIXME: could be pointing to stack area; must copy */ | ||
911 | probe_ent->pinfo2 = port[1]; | 911 | probe_ent->pinfo2 = port[1]; |
912 | } else | 912 | } else |
913 | probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; | 913 | probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; |
@@ -946,35 +946,21 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
946 | { | 946 | { |
947 | struct ata_probe_ent *probe_ent = NULL; | 947 | struct ata_probe_ent *probe_ent = NULL; |
948 | struct ata_port_info *port[2]; | 948 | struct ata_port_info *port[2]; |
949 | u8 tmp8, mask; | 949 | u8 mask; |
950 | unsigned int legacy_mode = 0; | 950 | unsigned int legacy_mode = 0; |
951 | int disable_dev_on_err = 1; | 951 | int disable_dev_on_err = 1; |
952 | int rc; | 952 | int rc; |
953 | 953 | ||
954 | DPRINTK("ENTER\n"); | 954 | DPRINTK("ENTER\n"); |
955 | 955 | ||
956 | BUG_ON(n_ports < 1 || n_ports > 2); | ||
957 | |||
956 | port[0] = port_info[0]; | 958 | port[0] = port_info[0]; |
957 | if (n_ports > 1) | 959 | if (n_ports > 1) |
958 | port[1] = port_info[1]; | 960 | port[1] = port_info[1]; |
959 | else | 961 | else |
960 | port[1] = port[0]; | 962 | port[1] = port[0]; |
961 | 963 | ||
962 | if ((port[0]->flags & ATA_FLAG_NO_LEGACY) == 0 | ||
963 | && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
964 | /* TODO: What if one channel is in native mode ... */ | ||
965 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); | ||
966 | mask = (1 << 2) | (1 << 0); | ||
967 | if ((tmp8 & mask) != mask) | ||
968 | legacy_mode = (1 << 3); | ||
969 | } | ||
970 | |||
971 | /* FIXME... */ | ||
972 | if ((!legacy_mode) && (n_ports > 2)) { | ||
973 | printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n"); | ||
974 | n_ports = 2; | ||
975 | /* For now */ | ||
976 | } | ||
977 | |||
978 | /* FIXME: Really for ATA it isn't safe because the device may be | 964 | /* FIXME: Really for ATA it isn't safe because the device may be |
979 | multi-purpose and we want to leave it alone if it was already | 965 | multi-purpose and we want to leave it alone if it was already |
980 | enabled. Secondly for shared use as Arjan says we want refcounting | 966 | enabled. Secondly for shared use as Arjan says we want refcounting |
@@ -987,6 +973,16 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
987 | if (rc) | 973 | if (rc) |
988 | return rc; | 974 | return rc; |
989 | 975 | ||
976 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
977 | u8 tmp8; | ||
978 | |||
979 | /* TODO: What if one channel is in native mode ... */ | ||
980 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); | ||
981 | mask = (1 << 2) | (1 << 0); | ||
982 | if ((tmp8 & mask) != mask) | ||
983 | legacy_mode = (1 << 3); | ||
984 | } | ||
985 | |||
990 | rc = pci_request_regions(pdev, DRV_NAME); | 986 | rc = pci_request_regions(pdev, DRV_NAME); |
991 | if (rc) { | 987 | if (rc) { |
992 | disable_dev_on_err = 0; | 988 | disable_dev_on_err = 0; |
@@ -1039,7 +1035,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1039 | goto err_out_regions; | 1035 | goto err_out_regions; |
1040 | } | 1036 | } |
1041 | 1037 | ||
1042 | /* FIXME: If we get no DMA mask we should fall back to PIO */ | 1038 | /* TODO: If we get no DMA mask we should fall back to PIO */ |
1043 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 1039 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); |
1044 | if (rc) | 1040 | if (rc) |
1045 | goto err_out_regions; | 1041 | goto err_out_regions; |
@@ -1062,13 +1058,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1062 | 1058 | ||
1063 | pci_set_master(pdev); | 1059 | pci_set_master(pdev); |
1064 | 1060 | ||
1065 | /* FIXME: check ata_device_add return */ | 1061 | if (!ata_device_add(probe_ent)) { |
1066 | ata_device_add(probe_ent); | 1062 | rc = -ENODEV; |
1063 | goto err_out_ent; | ||
1064 | } | ||
1067 | 1065 | ||
1068 | kfree(probe_ent); | 1066 | kfree(probe_ent); |
1069 | 1067 | ||
1070 | return 0; | 1068 | return 0; |
1071 | 1069 | ||
1070 | err_out_ent: | ||
1071 | kfree(probe_ent); | ||
1072 | err_out_regions: | 1072 | err_out_regions: |
1073 | if (legacy_mode & ATA_PORT_PRIMARY) | 1073 | if (legacy_mode & ATA_PORT_PRIMARY) |
1074 | release_region(ATA_PRIMARY_CMD, 8); | 1074 | release_region(ATA_PRIMARY_CMD, 8); |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 87af3b5861a..1d695df5860 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/dmi.h> | 34 | #include <linux/dmi.h> |
35 | 35 | ||
36 | #define DRV_NAME "pata_ali" | 36 | #define DRV_NAME "pata_ali" |
37 | #define DRV_VERSION "0.6.5" | 37 | #define DRV_VERSION "0.6.6" |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Cable special cases | 40 | * Cable special cases |
@@ -630,7 +630,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
630 | pci_read_config_byte(pdev, 0x53, &tmp); | 630 | pci_read_config_byte(pdev, 0x53, &tmp); |
631 | if (rev <= 0x20) | 631 | if (rev <= 0x20) |
632 | tmp &= ~0x02; | 632 | tmp &= ~0x02; |
633 | if (rev == 0xc7) | 633 | if (rev >= 0xc7) |
634 | tmp |= 0x03; | 634 | tmp |= 0x03; |
635 | else | 635 | else |
636 | tmp |= 0x01; /* CD_ROM enable for DMA */ | 636 | tmp |= 0x01; /* CD_ROM enable for DMA */ |
@@ -644,10 +644,11 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
644 | return ata_pci_init_one(pdev, port_info, 2); | 644 | return ata_pci_init_one(pdev, port_info, 2); |
645 | } | 645 | } |
646 | 646 | ||
647 | static struct pci_device_id ali[] = { | 647 | static const struct pci_device_id ali[] = { |
648 | { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228), }, | 648 | { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), }, |
649 | { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229), }, | 649 | { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), }, |
650 | { 0, }, | 650 | |
651 | { }, | ||
651 | }; | 652 | }; |
652 | 653 | ||
653 | static struct pci_driver ali_pci_driver = { | 654 | static struct pci_driver ali_pci_driver = { |
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 599ee266722..29234c89711 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -662,27 +662,28 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
662 | } | 662 | } |
663 | 663 | ||
664 | static const struct pci_device_id amd[] = { | 664 | static const struct pci_device_id amd[] = { |
665 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 665 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 }, |
666 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, | 666 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7409), 1 }, |
667 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, | 667 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7411), 3 }, |
668 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | 668 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_OPUS_7441), 4 }, |
669 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, | 669 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_8111_IDE), 5 }, |
670 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, | 670 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE), 7 }, |
671 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 671 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE), 8 }, |
672 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 672 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE), 8 }, |
673 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 673 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE), 8 }, |
674 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 674 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE), 8 }, |
675 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 675 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE), 8 }, |
676 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 676 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE), 8 }, |
677 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 677 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 }, |
678 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 678 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 }, |
679 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 679 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 }, |
680 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, | 680 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, |
681 | { 0, }, | 681 | |
682 | { }, | ||
682 | }; | 683 | }; |
683 | 684 | ||
684 | static struct pci_driver amd_pci_driver = { | 685 | static struct pci_driver amd_pci_driver = { |
685 | .name = DRV_NAME, | 686 | .name = DRV_NAME, |
686 | .id_table = amd, | 687 | .id_table = amd, |
687 | .probe = amd_init_one, | 688 | .probe = amd_init_one, |
688 | .remove = ata_pci_remove_one | 689 | .remove = ata_pci_remove_one |
@@ -698,7 +699,6 @@ static void __exit amd_exit(void) | |||
698 | pci_unregister_driver(&amd_pci_driver); | 699 | pci_unregister_driver(&amd_pci_driver); |
699 | } | 700 | } |
700 | 701 | ||
701 | |||
702 | MODULE_AUTHOR("Alan Cox"); | 702 | MODULE_AUTHOR("Alan Cox"); |
703 | MODULE_DESCRIPTION("low-level driver for AMD PATA IDE"); | 703 | MODULE_DESCRIPTION("low-level driver for AMD PATA IDE"); |
704 | MODULE_LICENSE("GPL"); | 704 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index c4ccb75a4f1..690828eb522 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c | |||
@@ -426,7 +426,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
426 | .port_ops = &artop6260_ops, | 426 | .port_ops = &artop6260_ops, |
427 | }; | 427 | }; |
428 | struct ata_port_info *port_info[2]; | 428 | struct ata_port_info *port_info[2]; |
429 | struct ata_port_info *info; | 429 | struct ata_port_info *info = NULL; |
430 | int ports = 2; | 430 | int ports = 2; |
431 | 431 | ||
432 | if (!printed_version++) | 432 | if (!printed_version++) |
@@ -470,16 +470,20 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
470 | pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); | 470 | pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); |
471 | 471 | ||
472 | } | 472 | } |
473 | |||
474 | BUG_ON(info == NULL); | ||
475 | |||
473 | port_info[0] = port_info[1] = info; | 476 | port_info[0] = port_info[1] = info; |
474 | return ata_pci_init_one(pdev, port_info, ports); | 477 | return ata_pci_init_one(pdev, port_info, ports); |
475 | } | 478 | } |
476 | 479 | ||
477 | static const struct pci_device_id artop_pci_tbl[] = { | 480 | static const struct pci_device_id artop_pci_tbl[] = { |
478 | { 0x1191, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 481 | { PCI_VDEVICE(ARTOP, 0x0005), 0 }, |
479 | { 0x1191, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 482 | { PCI_VDEVICE(ARTOP, 0x0006), 1 }, |
480 | { 0x1191, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 483 | { PCI_VDEVICE(ARTOP, 0x0007), 1 }, |
481 | { 0x1191, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | 484 | { PCI_VDEVICE(ARTOP, 0x0008), 2 }, |
482 | { 0x1191, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | 485 | { PCI_VDEVICE(ARTOP, 0x0009), 2 }, |
486 | |||
483 | { } /* terminate list */ | 487 | { } /* terminate list */ |
484 | }; | 488 | }; |
485 | 489 | ||
@@ -500,7 +504,6 @@ static void __exit artop_exit(void) | |||
500 | pci_unregister_driver(&artop_pci_driver); | 504 | pci_unregister_driver(&artop_pci_driver); |
501 | } | 505 | } |
502 | 506 | ||
503 | |||
504 | module_init(artop_init); | 507 | module_init(artop_init); |
505 | module_exit(artop_exit); | 508 | module_exit(artop_exit); |
506 | 509 | ||
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 6c2269b6bd3..1ce28d2125f 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c | |||
@@ -267,12 +267,13 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
267 | return ata_pci_init_one(dev, port_info, 2); | 267 | return ata_pci_init_one(dev, port_info, 2); |
268 | } | 268 | } |
269 | 269 | ||
270 | static struct pci_device_id atiixp[] = { | 270 | static const struct pci_device_id atiixp[] = { |
271 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), }, | 271 | { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), }, |
272 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), }, | 272 | { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), }, |
273 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), }, | 273 | { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), }, |
274 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), }, | 274 | { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), }, |
275 | { 0, }, | 275 | |
276 | { }, | ||
276 | }; | 277 | }; |
277 | 278 | ||
278 | static struct pci_driver atiixp_pci_driver = { | 279 | static struct pci_driver atiixp_pci_driver = { |
@@ -293,7 +294,6 @@ static void __exit atiixp_exit(void) | |||
293 | pci_unregister_driver(&atiixp_pci_driver); | 294 | pci_unregister_driver(&atiixp_pci_driver); |
294 | } | 295 | } |
295 | 296 | ||
296 | |||
297 | MODULE_AUTHOR("Alan Cox"); | 297 | MODULE_AUTHOR("Alan Cox"); |
298 | MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400"); | 298 | MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400"); |
299 | MODULE_LICENSE("GPL"); | 299 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index e92b0ef43ec..b9bbd1d454b 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -468,16 +468,17 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
468 | return ata_pci_init_one(pdev, port_info, 2); | 468 | return ata_pci_init_one(pdev, port_info, 2); |
469 | } | 469 | } |
470 | 470 | ||
471 | static struct pci_device_id cmd64x[] = { | 471 | static const struct pci_device_id cmd64x[] = { |
472 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 472 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, |
473 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 473 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 }, |
474 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, | 474 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 4 }, |
475 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, | 475 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 5 }, |
476 | { 0, }, | 476 | |
477 | { }, | ||
477 | }; | 478 | }; |
478 | 479 | ||
479 | static struct pci_driver cmd64x_pci_driver = { | 480 | static struct pci_driver cmd64x_pci_driver = { |
480 | .name = DRV_NAME, | 481 | .name = DRV_NAME, |
481 | .id_table = cmd64x, | 482 | .id_table = cmd64x, |
482 | .probe = cmd64x_init_one, | 483 | .probe = cmd64x_init_one, |
483 | .remove = ata_pci_remove_one | 484 | .remove = ata_pci_remove_one |
@@ -488,13 +489,11 @@ static int __init cmd64x_init(void) | |||
488 | return pci_register_driver(&cmd64x_pci_driver); | 489 | return pci_register_driver(&cmd64x_pci_driver); |
489 | } | 490 | } |
490 | 491 | ||
491 | |||
492 | static void __exit cmd64x_exit(void) | 492 | static void __exit cmd64x_exit(void) |
493 | { | 493 | { |
494 | pci_unregister_driver(&cmd64x_pci_driver); | 494 | pci_unregister_driver(&cmd64x_pci_driver); |
495 | } | 495 | } |
496 | 496 | ||
497 | |||
498 | MODULE_AUTHOR("Alan Cox"); | 497 | MODULE_AUTHOR("Alan Cox"); |
499 | MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers"); | 498 | MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers"); |
500 | MODULE_LICENSE("GPL"); | 499 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index a6c6cebd0da..2cd3c0ff76d 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -299,10 +299,11 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev) | |||
299 | /* For now keep DMA off. We can set it for all but A rev CS5510 once the | 299 | /* For now keep DMA off. We can set it for all but A rev CS5510 once the |
300 | core ATA code can handle it */ | 300 | core ATA code can handle it */ |
301 | 301 | ||
302 | static struct pci_device_id pata_cs5520[] = { | 302 | static const struct pci_device_id pata_cs5520[] = { |
303 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, | 303 | { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, |
304 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520), }, | 304 | { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), }, |
305 | { 0, }, | 305 | |
306 | { }, | ||
306 | }; | 307 | }; |
307 | 308 | ||
308 | static struct pci_driver cs5520_pci_driver = { | 309 | static struct pci_driver cs5520_pci_driver = { |
@@ -312,7 +313,6 @@ static struct pci_driver cs5520_pci_driver = { | |||
312 | .remove = cs5520_remove_one | 313 | .remove = cs5520_remove_one |
313 | }; | 314 | }; |
314 | 315 | ||
315 | |||
316 | static int __init cs5520_init(void) | 316 | static int __init cs5520_init(void) |
317 | { | 317 | { |
318 | return pci_register_driver(&cs5520_pci_driver); | 318 | return pci_register_driver(&cs5520_pci_driver); |
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 7bba4d954e9..a07cc81ef79 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c | |||
@@ -353,13 +353,14 @@ fail_put: | |||
353 | return -ENODEV; | 353 | return -ENODEV; |
354 | } | 354 | } |
355 | 355 | ||
356 | static struct pci_device_id cs5530[] = { | 356 | static const struct pci_device_id cs5530[] = { |
357 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, | 357 | { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, |
358 | { 0, }, | 358 | |
359 | { }, | ||
359 | }; | 360 | }; |
360 | 361 | ||
361 | static struct pci_driver cs5530_pci_driver = { | 362 | static struct pci_driver cs5530_pci_driver = { |
362 | .name = DRV_NAME, | 363 | .name = DRV_NAME, |
363 | .id_table = cs5530, | 364 | .id_table = cs5530, |
364 | .probe = cs5530_init_one, | 365 | .probe = cs5530_init_one, |
365 | .remove = ata_pci_remove_one | 366 | .remove = ata_pci_remove_one |
@@ -370,13 +371,11 @@ static int __init cs5530_init(void) | |||
370 | return pci_register_driver(&cs5530_pci_driver); | 371 | return pci_register_driver(&cs5530_pci_driver); |
371 | } | 372 | } |
372 | 373 | ||
373 | |||
374 | static void __exit cs5530_exit(void) | 374 | static void __exit cs5530_exit(void) |
375 | { | 375 | { |
376 | pci_unregister_driver(&cs5530_pci_driver); | 376 | pci_unregister_driver(&cs5530_pci_driver); |
377 | } | 377 | } |
378 | 378 | ||
379 | |||
380 | MODULE_AUTHOR("Alan Cox"); | 379 | MODULE_AUTHOR("Alan Cox"); |
381 | MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530"); | 380 | MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530"); |
382 | MODULE_LICENSE("GPL"); | 381 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index d64fcdceaf0..f8def3f9c61 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c | |||
@@ -257,9 +257,10 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
257 | return ata_pci_init_one(dev, ports, 1); | 257 | return ata_pci_init_one(dev, ports, 1); |
258 | } | 258 | } |
259 | 259 | ||
260 | static struct pci_device_id cs5535[] = { | 260 | static const struct pci_device_id cs5535[] = { |
261 | { PCI_DEVICE(PCI_VENDOR_ID_NS, 0x002D), }, | 261 | { PCI_VDEVICE(NS, 0x002D), }, |
262 | { 0, }, | 262 | |
263 | { }, | ||
263 | }; | 264 | }; |
264 | 265 | ||
265 | static struct pci_driver cs5535_pci_driver = { | 266 | static struct pci_driver cs5535_pci_driver = { |
@@ -274,13 +275,11 @@ static int __init cs5535_init(void) | |||
274 | return pci_register_driver(&cs5535_pci_driver); | 275 | return pci_register_driver(&cs5535_pci_driver); |
275 | } | 276 | } |
276 | 277 | ||
277 | |||
278 | static void __exit cs5535_exit(void) | 278 | static void __exit cs5535_exit(void) |
279 | { | 279 | { |
280 | pci_unregister_driver(&cs5535_pci_driver); | 280 | pci_unregister_driver(&cs5535_pci_driver); |
281 | } | 281 | } |
282 | 282 | ||
283 | |||
284 | MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch"); | 283 | MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch"); |
285 | MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530"); | 284 | MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530"); |
286 | MODULE_LICENSE("GPL"); | 285 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index dfa5ac53904..247b43608b1 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c | |||
@@ -184,8 +184,8 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i | |||
184 | }; | 184 | }; |
185 | static struct ata_port_info *port_info[1] = { &info }; | 185 | static struct ata_port_info *port_info[1] = { &info }; |
186 | 186 | ||
187 | /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the | 187 | /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. |
188 | moment we don't handle the secondary. FIXME */ | 188 | For the moment we don't handle the secondary. FIXME */ |
189 | 189 | ||
190 | if (PCI_FUNC(pdev->devfn) != 1) | 190 | if (PCI_FUNC(pdev->devfn) != 1) |
191 | return -ENODEV; | 191 | return -ENODEV; |
@@ -193,13 +193,14 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i | |||
193 | return ata_pci_init_one(pdev, port_info, 1); | 193 | return ata_pci_init_one(pdev, port_info, 1); |
194 | } | 194 | } |
195 | 195 | ||
196 | static struct pci_device_id cy82c693[] = { | 196 | static const struct pci_device_id cy82c693[] = { |
197 | { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 197 | { PCI_VDEVICE(CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693), }, |
198 | { 0, }, | 198 | |
199 | { }, | ||
199 | }; | 200 | }; |
200 | 201 | ||
201 | static struct pci_driver cy82c693_pci_driver = { | 202 | static struct pci_driver cy82c693_pci_driver = { |
202 | .name = DRV_NAME, | 203 | .name = DRV_NAME, |
203 | .id_table = cy82c693, | 204 | .id_table = cy82c693, |
204 | .probe = cy82c693_init_one, | 205 | .probe = cy82c693_init_one, |
205 | .remove = ata_pci_remove_one | 206 | .remove = ata_pci_remove_one |
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 95cd1ca181f..ef18c60fe14 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -305,7 +305,8 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
305 | } | 305 | } |
306 | 306 | ||
307 | static const struct pci_device_id efar_pci_tbl[] = { | 307 | static const struct pci_device_id efar_pci_tbl[] = { |
308 | { 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, }, | 308 | { PCI_VDEVICE(EFAR, 0x9130), }, |
309 | |||
309 | { } /* terminate list */ | 310 | { } /* terminate list */ |
310 | }; | 311 | }; |
311 | 312 | ||
@@ -326,7 +327,6 @@ static void __exit efar_exit(void) | |||
326 | pci_unregister_driver(&efar_pci_driver); | 327 | pci_unregister_driver(&efar_pci_driver); |
327 | } | 328 | } |
328 | 329 | ||
329 | |||
330 | module_init(efar_init); | 330 | module_init(efar_init); |
331 | module_exit(efar_exit); | 331 | module_exit(efar_exit); |
332 | 332 | ||
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 8c757438f35..6d3e4c0f15f 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -444,13 +444,14 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
444 | return ata_pci_init_one(dev, port_info, 2); | 444 | return ata_pci_init_one(dev, port_info, 2); |
445 | } | 445 | } |
446 | 446 | ||
447 | static struct pci_device_id hpt36x[] = { | 447 | static const struct pci_device_id hpt36x[] = { |
448 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, | 448 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, |
449 | { 0, }, | 449 | |
450 | { }, | ||
450 | }; | 451 | }; |
451 | 452 | ||
452 | static struct pci_driver hpt36x_pci_driver = { | 453 | static struct pci_driver hpt36x_pci_driver = { |
453 | .name = DRV_NAME, | 454 | .name = DRV_NAME, |
454 | .id_table = hpt36x, | 455 | .id_table = hpt36x, |
455 | .probe = hpt36x_init_one, | 456 | .probe = hpt36x_init_one, |
456 | .remove = ata_pci_remove_one | 457 | .remove = ata_pci_remove_one |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 10318c0012e..7350443948c 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -1219,17 +1219,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
1219 | return ata_pci_init_one(dev, port_info, 2); | 1219 | return ata_pci_init_one(dev, port_info, 2); |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | static struct pci_device_id hpt37x[] = { | 1222 | static const struct pci_device_id hpt37x[] = { |
1223 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, | 1223 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, |
1224 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371), }, | 1224 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), }, |
1225 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, | 1225 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), }, |
1226 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374), }, | 1226 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), }, |
1227 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, | 1227 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), }, |
1228 | { 0, }, | 1228 | |
1229 | { }, | ||
1229 | }; | 1230 | }; |
1230 | 1231 | ||
1231 | static struct pci_driver hpt37x_pci_driver = { | 1232 | static struct pci_driver hpt37x_pci_driver = { |
1232 | .name = DRV_NAME, | 1233 | .name = DRV_NAME, |
1233 | .id_table = hpt37x, | 1234 | .id_table = hpt37x, |
1234 | .probe = hpt37x_init_one, | 1235 | .probe = hpt37x_init_one, |
1235 | .remove = ata_pci_remove_one | 1236 | .remove = ata_pci_remove_one |
@@ -1240,13 +1241,11 @@ static int __init hpt37x_init(void) | |||
1240 | return pci_register_driver(&hpt37x_pci_driver); | 1241 | return pci_register_driver(&hpt37x_pci_driver); |
1241 | } | 1242 | } |
1242 | 1243 | ||
1243 | |||
1244 | static void __exit hpt37x_exit(void) | 1244 | static void __exit hpt37x_exit(void) |
1245 | { | 1245 | { |
1246 | pci_unregister_driver(&hpt37x_pci_driver); | 1246 | pci_unregister_driver(&hpt37x_pci_driver); |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | |||
1250 | MODULE_AUTHOR("Alan Cox"); | 1249 | MODULE_AUTHOR("Alan Cox"); |
1251 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x"); | 1250 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x"); |
1252 | MODULE_LICENSE("GPL"); | 1251 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 5c5d4f6ab90..58cfb2bc809 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -560,16 +560,17 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
560 | return ata_pci_init_one(dev, port_info, 2); | 560 | return ata_pci_init_one(dev, port_info, 2); |
561 | } | 561 | } |
562 | 562 | ||
563 | static struct pci_device_id hpt3x2n[] = { | 563 | static const struct pci_device_id hpt3x2n[] = { |
564 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, | 564 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, |
565 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, | 565 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), }, |
566 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, | 566 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), }, |
567 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N), }, | 567 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), }, |
568 | { 0, }, | 568 | |
569 | { }, | ||
569 | }; | 570 | }; |
570 | 571 | ||
571 | static struct pci_driver hpt3x2n_pci_driver = { | 572 | static struct pci_driver hpt3x2n_pci_driver = { |
572 | .name = DRV_NAME, | 573 | .name = DRV_NAME, |
573 | .id_table = hpt3x2n, | 574 | .id_table = hpt3x2n, |
574 | .probe = hpt3x2n_init_one, | 575 | .probe = hpt3x2n_init_one, |
575 | .remove = ata_pci_remove_one | 576 | .remove = ata_pci_remove_one |
@@ -580,13 +581,11 @@ static int __init hpt3x2n_init(void) | |||
580 | return pci_register_driver(&hpt3x2n_pci_driver); | 581 | return pci_register_driver(&hpt3x2n_pci_driver); |
581 | } | 582 | } |
582 | 583 | ||
583 | |||
584 | static void __exit hpt3x2n_exit(void) | 584 | static void __exit hpt3x2n_exit(void) |
585 | { | 585 | { |
586 | pci_unregister_driver(&hpt3x2n_pci_driver); | 586 | pci_unregister_driver(&hpt3x2n_pci_driver); |
587 | } | 587 | } |
588 | 588 | ||
589 | |||
590 | MODULE_AUTHOR("Alan Cox"); | 589 | MODULE_AUTHOR("Alan Cox"); |
591 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); | 590 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); |
592 | MODULE_LICENSE("GPL"); | 591 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 1f084ab1ccc..3334d72e251 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c | |||
@@ -192,13 +192,14 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
192 | return ata_pci_init_one(dev, port_info, 2); | 192 | return ata_pci_init_one(dev, port_info, 2); |
193 | } | 193 | } |
194 | 194 | ||
195 | static struct pci_device_id hpt3x3[] = { | 195 | static const struct pci_device_id hpt3x3[] = { |
196 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343), }, | 196 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), }, |
197 | { 0, }, | 197 | |
198 | { }, | ||
198 | }; | 199 | }; |
199 | 200 | ||
200 | static struct pci_driver hpt3x3_pci_driver = { | 201 | static struct pci_driver hpt3x3_pci_driver = { |
201 | .name = DRV_NAME, | 202 | .name = DRV_NAME, |
202 | .id_table = hpt3x3, | 203 | .id_table = hpt3x3, |
203 | .probe = hpt3x3_init_one, | 204 | .probe = hpt3x3_init_one, |
204 | .remove = ata_pci_remove_one | 205 | .remove = ata_pci_remove_one |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 82a46ff4000..18ff3e59a89 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -808,14 +808,15 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
808 | return ata_pci_init_one(pdev, port_info, 2); | 808 | return ata_pci_init_one(pdev, port_info, 2); |
809 | } | 809 | } |
810 | 810 | ||
811 | static struct pci_device_id it821x[] = { | 811 | static const struct pci_device_id it821x[] = { |
812 | { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211), }, | 812 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), }, |
813 | { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212), }, | 813 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), }, |
814 | { 0, }, | 814 | |
815 | { }, | ||
815 | }; | 816 | }; |
816 | 817 | ||
817 | static struct pci_driver it821x_pci_driver = { | 818 | static struct pci_driver it821x_pci_driver = { |
818 | .name = DRV_NAME, | 819 | .name = DRV_NAME, |
819 | .id_table = it821x, | 820 | .id_table = it821x, |
820 | .probe = it821x_init_one, | 821 | .probe = it821x_init_one, |
821 | .remove = ata_pci_remove_one | 822 | .remove = ata_pci_remove_one |
@@ -826,13 +827,11 @@ static int __init it821x_init(void) | |||
826 | return pci_register_driver(&it821x_pci_driver); | 827 | return pci_register_driver(&it821x_pci_driver); |
827 | } | 828 | } |
828 | 829 | ||
829 | |||
830 | static void __exit it821x_exit(void) | 830 | static void __exit it821x_exit(void) |
831 | { | 831 | { |
832 | pci_unregister_driver(&it821x_pci_driver); | 832 | pci_unregister_driver(&it821x_pci_driver); |
833 | } | 833 | } |
834 | 834 | ||
835 | |||
836 | MODULE_AUTHOR("Alan Cox"); | 835 | MODULE_AUTHOR("Alan Cox"); |
837 | MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller"); | 836 | MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller"); |
838 | MODULE_LICENSE("GPL"); | 837 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index be3a866b111..52a2bdf3c38 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c | |||
@@ -229,11 +229,12 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
229 | } | 229 | } |
230 | 230 | ||
231 | static const struct pci_device_id jmicron_pci_tbl[] = { | 231 | static const struct pci_device_id jmicron_pci_tbl[] = { |
232 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361}, | 232 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361}, |
233 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363}, | 233 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363}, |
234 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365}, | 234 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365}, |
235 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366}, | 235 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366}, |
236 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368}, | 236 | { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368}, |
237 | |||
237 | { } /* terminate list */ | 238 | { } /* terminate list */ |
238 | }; | 239 | }; |
239 | 240 | ||
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index 3c65393c1f0..9dfe3e9abea 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c | |||
@@ -274,11 +274,10 @@ static void __devexit mpiix_remove_one(struct pci_dev *pdev) | |||
274 | dev_set_drvdata(dev, NULL); | 274 | dev_set_drvdata(dev, NULL); |
275 | } | 275 | } |
276 | 276 | ||
277 | |||
278 | |||
279 | static const struct pci_device_id mpiix[] = { | 277 | static const struct pci_device_id mpiix[] = { |
280 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX), }, | 278 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), }, |
281 | { 0, }, | 279 | |
280 | { }, | ||
282 | }; | 281 | }; |
283 | 282 | ||
284 | static struct pci_driver mpiix_pci_driver = { | 283 | static struct pci_driver mpiix_pci_driver = { |
@@ -293,13 +292,11 @@ static int __init mpiix_init(void) | |||
293 | return pci_register_driver(&mpiix_pci_driver); | 292 | return pci_register_driver(&mpiix_pci_driver); |
294 | } | 293 | } |
295 | 294 | ||
296 | |||
297 | static void __exit mpiix_exit(void) | 295 | static void __exit mpiix_exit(void) |
298 | { | 296 | { |
299 | pci_unregister_driver(&mpiix_pci_driver); | 297 | pci_unregister_driver(&mpiix_pci_driver); |
300 | } | 298 | } |
301 | 299 | ||
302 | |||
303 | MODULE_AUTHOR("Alan Cox"); | 300 | MODULE_AUTHOR("Alan Cox"); |
304 | MODULE_DESCRIPTION("low-level driver for Intel MPIIX"); | 301 | MODULE_DESCRIPTION("low-level driver for Intel MPIIX"); |
305 | MODULE_LICENSE("GPL"); | 302 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 76eb9c90bee..f5672de99c2 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c | |||
@@ -142,7 +142,8 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
142 | } | 142 | } |
143 | 143 | ||
144 | static const struct pci_device_id netcell_pci_tbl[] = { | 144 | static const struct pci_device_id netcell_pci_tbl[] = { |
145 | { PCI_DEVICE(PCI_VENDOR_ID_NETCELL, PCI_DEVICE_ID_REVOLUTION), }, | 145 | { PCI_VDEVICE(NETCELL, PCI_DEVICE_ID_REVOLUTION), }, |
146 | |||
146 | { } /* terminate list */ | 147 | { } /* terminate list */ |
147 | }; | 148 | }; |
148 | 149 | ||
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index 2005a95f48f..2a3dbeed89b 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c | |||
@@ -200,12 +200,13 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | static const struct pci_device_id ns87410[] = { | 202 | static const struct pci_device_id ns87410[] = { |
203 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), }, | 203 | { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87410), }, |
204 | { 0, }, | 204 | |
205 | { }, | ||
205 | }; | 206 | }; |
206 | 207 | ||
207 | static struct pci_driver ns87410_pci_driver = { | 208 | static struct pci_driver ns87410_pci_driver = { |
208 | .name = DRV_NAME, | 209 | .name = DRV_NAME, |
209 | .id_table = ns87410, | 210 | .id_table = ns87410, |
210 | .probe = ns87410_init_one, | 211 | .probe = ns87410_init_one, |
211 | .remove = ata_pci_remove_one | 212 | .remove = ata_pci_remove_one |
@@ -216,13 +217,11 @@ static int __init ns87410_init(void) | |||
216 | return pci_register_driver(&ns87410_pci_driver); | 217 | return pci_register_driver(&ns87410_pci_driver); |
217 | } | 218 | } |
218 | 219 | ||
219 | |||
220 | static void __exit ns87410_exit(void) | 220 | static void __exit ns87410_exit(void) |
221 | { | 221 | { |
222 | pci_unregister_driver(&ns87410_pci_driver); | 222 | pci_unregister_driver(&ns87410_pci_driver); |
223 | } | 223 | } |
224 | 224 | ||
225 | |||
226 | MODULE_AUTHOR("Alan Cox"); | 225 | MODULE_AUTHOR("Alan Cox"); |
227 | MODULE_DESCRIPTION("low-level driver for Nat Semi 87410"); | 226 | MODULE_DESCRIPTION("low-level driver for Nat Semi 87410"); |
228 | MODULE_LICENSE("GPL"); | 227 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 31a285ca88d..fc947dfecd7 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c | |||
@@ -303,7 +303,8 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
303 | } | 303 | } |
304 | 304 | ||
305 | static const struct pci_device_id oldpiix_pci_tbl[] = { | 305 | static const struct pci_device_id oldpiix_pci_tbl[] = { |
306 | { PCI_DEVICE(0x8086, 0x1230), }, | 306 | { PCI_VDEVICE(INTEL, 0x1230), }, |
307 | |||
307 | { } /* terminate list */ | 308 | { } /* terminate list */ |
308 | }; | 309 | }; |
309 | 310 | ||
@@ -324,7 +325,6 @@ static void __exit oldpiix_exit(void) | |||
324 | pci_unregister_driver(&oldpiix_pci_driver); | 325 | pci_unregister_driver(&oldpiix_pci_driver); |
325 | } | 326 | } |
326 | 327 | ||
327 | |||
328 | module_init(oldpiix_init); | 328 | module_init(oldpiix_init); |
329 | module_exit(oldpiix_exit); | 329 | module_exit(oldpiix_exit); |
330 | 330 | ||
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index 57fe21f3a97..a7320ba1557 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c | |||
@@ -256,13 +256,14 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
256 | } | 256 | } |
257 | 257 | ||
258 | static const struct pci_device_id opti[] = { | 258 | static const struct pci_device_id opti[] = { |
259 | { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 259 | { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 }, |
260 | { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 260 | { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 1 }, |
261 | { 0, }, | 261 | |
262 | { }, | ||
262 | }; | 263 | }; |
263 | 264 | ||
264 | static struct pci_driver opti_pci_driver = { | 265 | static struct pci_driver opti_pci_driver = { |
265 | .name = DRV_NAME, | 266 | .name = DRV_NAME, |
266 | .id_table = opti, | 267 | .id_table = opti, |
267 | .probe = opti_init_one, | 268 | .probe = opti_init_one, |
268 | .remove = ata_pci_remove_one | 269 | .remove = ata_pci_remove_one |
@@ -273,7 +274,6 @@ static int __init opti_init(void) | |||
273 | return pci_register_driver(&opti_pci_driver); | 274 | return pci_register_driver(&opti_pci_driver); |
274 | } | 275 | } |
275 | 276 | ||
276 | |||
277 | static void __exit opti_exit(void) | 277 | static void __exit opti_exit(void) |
278 | { | 278 | { |
279 | pci_unregister_driver(&opti_pci_driver); | 279 | pci_unregister_driver(&opti_pci_driver); |
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 7296a20cd10..c6906b4215d 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c | |||
@@ -512,12 +512,13 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
512 | } | 512 | } |
513 | 513 | ||
514 | static const struct pci_device_id optidma[] = { | 514 | static const struct pci_device_id optidma[] = { |
515 | { PCI_DEVICE(0x1045, 0xD568), }, /* Opti 82C700 */ | 515 | { PCI_VDEVICE(OPTI, 0xD568), }, /* Opti 82C700 */ |
516 | { 0, }, | 516 | |
517 | { }, | ||
517 | }; | 518 | }; |
518 | 519 | ||
519 | static struct pci_driver optidma_pci_driver = { | 520 | static struct pci_driver optidma_pci_driver = { |
520 | .name = DRV_NAME, | 521 | .name = DRV_NAME, |
521 | .id_table = optidma, | 522 | .id_table = optidma, |
522 | .probe = optidma_init_one, | 523 | .probe = optidma_init_one, |
523 | .remove = ata_pci_remove_one | 524 | .remove = ata_pci_remove_one |
@@ -528,13 +529,11 @@ static int __init optidma_init(void) | |||
528 | return pci_register_driver(&optidma_pci_driver); | 529 | return pci_register_driver(&optidma_pci_driver); |
529 | } | 530 | } |
530 | 531 | ||
531 | |||
532 | static void __exit optidma_exit(void) | 532 | static void __exit optidma_exit(void) |
533 | { | 533 | { |
534 | pci_unregister_driver(&optidma_pci_driver); | 534 | pci_unregister_driver(&optidma_pci_driver); |
535 | } | 535 | } |
536 | 536 | ||
537 | |||
538 | MODULE_AUTHOR("Alan Cox"); | 537 | MODULE_AUTHOR("Alan Cox"); |
539 | MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus"); | 538 | MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus"); |
540 | MODULE_LICENSE("GPL"); | 539 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index cb501e145a4..e93ea2702c7 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | 43 | ||
44 | #define DRV_NAME "pata_pcmcia" | 44 | #define DRV_NAME "pata_pcmcia" |
45 | #define DRV_VERSION "0.2.9" | 45 | #define DRV_VERSION "0.2.11" |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Private data structure to glue stuff together | 48 | * Private data structure to glue stuff together |
@@ -355,6 +355,8 @@ static struct pcmcia_device_id pcmcia_devices[] = { | |||
355 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), | 355 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), |
356 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), | 356 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), |
357 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | 357 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), |
358 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), | ||
359 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), | ||
358 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | 360 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), |
359 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 361 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
360 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 362 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index bd4ed6734ed..d894d9918b1 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
@@ -108,13 +108,14 @@ static struct pdc2027x_udma_timing { | |||
108 | }; | 108 | }; |
109 | 109 | ||
110 | static const struct pci_device_id pdc2027x_pci_tbl[] = { | 110 | static const struct pci_device_id pdc2027x_pci_tbl[] = { |
111 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 }, | 111 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), PDC_UDMA_100 }, |
112 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, | 112 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), PDC_UDMA_133 }, |
113 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 }, | 113 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), PDC_UDMA_100 }, |
114 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, | 114 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), PDC_UDMA_133 }, |
115 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, | 115 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), PDC_UDMA_133 }, |
116 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, | 116 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), PDC_UDMA_133 }, |
117 | { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 }, | 117 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), PDC_UDMA_133 }, |
118 | |||
118 | { } /* terminate list */ | 119 | { } /* terminate list */ |
119 | }; | 120 | }; |
120 | 121 | ||
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 48f43432764..5ba9eb20a6c 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c | |||
@@ -385,17 +385,18 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
385 | return ata_pci_init_one(dev, port_info, 2); | 385 | return ata_pci_init_one(dev, port_info, 2); |
386 | } | 386 | } |
387 | 387 | ||
388 | static struct pci_device_id pdc[] = { | 388 | static const struct pci_device_id pdc[] = { |
389 | { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0}, | 389 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 }, |
390 | { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1}, | 390 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 }, |
391 | { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1}, | 391 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 }, |
392 | { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2}, | 392 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2 }, |
393 | { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2}, | 393 | { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2 }, |
394 | { 0, }, | 394 | |
395 | { }, | ||
395 | }; | 396 | }; |
396 | 397 | ||
397 | static struct pci_driver pdc_pci_driver = { | 398 | static struct pci_driver pdc_pci_driver = { |
398 | .name = DRV_NAME, | 399 | .name = DRV_NAME, |
399 | .id_table = pdc, | 400 | .id_table = pdc, |
400 | .probe = pdc_init_one, | 401 | .probe = pdc_init_one, |
401 | .remove = ata_pci_remove_one | 402 | .remove = ata_pci_remove_one |
@@ -406,13 +407,11 @@ static int __init pdc_init(void) | |||
406 | return pci_register_driver(&pdc_pci_driver); | 407 | return pci_register_driver(&pdc_pci_driver); |
407 | } | 408 | } |
408 | 409 | ||
409 | |||
410 | static void __exit pdc_exit(void) | 410 | static void __exit pdc_exit(void) |
411 | { | 411 | { |
412 | pci_unregister_driver(&pdc_pci_driver); | 412 | pci_unregister_driver(&pdc_pci_driver); |
413 | } | 413 | } |
414 | 414 | ||
415 | |||
416 | MODULE_AUTHOR("Alan Cox"); | 415 | MODULE_AUTHOR("Alan Cox"); |
417 | MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267"); | 416 | MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267"); |
418 | MODULE_LICENSE("GPL"); | 417 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index c20bcf43ed6..1af83d7694d 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c | |||
@@ -300,7 +300,8 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
300 | } | 300 | } |
301 | 301 | ||
302 | static const struct pci_device_id radisys_pci_tbl[] = { | 302 | static const struct pci_device_id radisys_pci_tbl[] = { |
303 | { 0x1331, 0x8201, PCI_ANY_ID, PCI_ANY_ID, }, | 303 | { PCI_VDEVICE(RADISYS, 0x8201), }, |
304 | |||
304 | { } /* terminate list */ | 305 | { } /* terminate list */ |
305 | }; | 306 | }; |
306 | 307 | ||
@@ -321,7 +322,6 @@ static void __exit radisys_exit(void) | |||
321 | pci_unregister_driver(&radisys_pci_driver); | 322 | pci_unregister_driver(&radisys_pci_driver); |
322 | } | 323 | } |
323 | 324 | ||
324 | |||
325 | module_init(radisys_init); | 325 | module_init(radisys_init); |
326 | module_exit(radisys_exit); | 326 | module_exit(radisys_exit); |
327 | 327 | ||
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index eccc6fd4503..4533b6357d9 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c | |||
@@ -170,20 +170,20 @@ fail: | |||
170 | return -ENODEV; | 170 | return -ENODEV; |
171 | } | 171 | } |
172 | 172 | ||
173 | static struct pci_device_id pata_rz1000[] = { | 173 | static const struct pci_device_id pata_rz1000[] = { |
174 | { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), }, | 174 | { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), }, |
175 | { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), }, | 175 | { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), }, |
176 | { 0, }, | 176 | |
177 | { }, | ||
177 | }; | 178 | }; |
178 | 179 | ||
179 | static struct pci_driver rz1000_pci_driver = { | 180 | static struct pci_driver rz1000_pci_driver = { |
180 | .name = DRV_NAME, | 181 | .name = DRV_NAME, |
181 | .id_table = pata_rz1000, | 182 | .id_table = pata_rz1000, |
182 | .probe = rz1000_init_one, | 183 | .probe = rz1000_init_one, |
183 | .remove = ata_pci_remove_one | 184 | .remove = ata_pci_remove_one |
184 | }; | 185 | }; |
185 | 186 | ||
186 | |||
187 | static int __init rz1000_init(void) | 187 | static int __init rz1000_init(void) |
188 | { | 188 | { |
189 | return pci_register_driver(&rz1000_pci_driver); | 189 | return pci_register_driver(&rz1000_pci_driver); |
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 107e6cd3dc0..067d9d223e3 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c | |||
@@ -253,13 +253,14 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
253 | return ata_pci_init_one(dev, port_info, 1); | 253 | return ata_pci_init_one(dev, port_info, 1); |
254 | } | 254 | } |
255 | 255 | ||
256 | static struct pci_device_id sc1200[] = { | 256 | static const struct pci_device_id sc1200[] = { |
257 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), }, | 257 | { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_IDE), }, |
258 | { 0, }, | 258 | |
259 | { }, | ||
259 | }; | 260 | }; |
260 | 261 | ||
261 | static struct pci_driver sc1200_pci_driver = { | 262 | static struct pci_driver sc1200_pci_driver = { |
262 | .name = DRV_NAME, | 263 | .name = DRV_NAME, |
263 | .id_table = sc1200, | 264 | .id_table = sc1200, |
264 | .probe = sc1200_init_one, | 265 | .probe = sc1200_init_one, |
265 | .remove = ata_pci_remove_one | 266 | .remove = ata_pci_remove_one |
@@ -270,13 +271,11 @@ static int __init sc1200_init(void) | |||
270 | return pci_register_driver(&sc1200_pci_driver); | 271 | return pci_register_driver(&sc1200_pci_driver); |
271 | } | 272 | } |
272 | 273 | ||
273 | |||
274 | static void __exit sc1200_exit(void) | 274 | static void __exit sc1200_exit(void) |
275 | { | 275 | { |
276 | pci_unregister_driver(&sc1200_pci_driver); | 276 | pci_unregister_driver(&sc1200_pci_driver); |
277 | } | 277 | } |
278 | 278 | ||
279 | |||
280 | MODULE_AUTHOR("Alan Cox, Mark Lord"); | 279 | MODULE_AUTHOR("Alan Cox, Mark Lord"); |
281 | MODULE_DESCRIPTION("low-level driver for the NS/AMD SC1200"); | 280 | MODULE_DESCRIPTION("low-level driver for the NS/AMD SC1200"); |
282 | MODULE_LICENSE("GPL"); | 281 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index a5c8d7e121d..5bbf76ec14a 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c | |||
@@ -553,13 +553,14 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id | |||
553 | return ata_pci_init_one(pdev, port_info, ports); | 553 | return ata_pci_init_one(pdev, port_info, ports); |
554 | } | 554 | } |
555 | 555 | ||
556 | static struct pci_device_id serverworks[] = { | 556 | static const struct pci_device_id serverworks[] = { |
557 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, | 557 | { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, |
558 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2}, | 558 | { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2}, |
559 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2}, | 559 | { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2}, |
560 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2}, | 560 | { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2}, |
561 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2}, | 561 | { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2}, |
562 | { 0, }, | 562 | |
563 | { }, | ||
563 | }; | 564 | }; |
564 | 565 | ||
565 | static struct pci_driver serverworks_pci_driver = { | 566 | static struct pci_driver serverworks_pci_driver = { |
@@ -574,13 +575,11 @@ static int __init serverworks_init(void) | |||
574 | return pci_register_driver(&serverworks_pci_driver); | 575 | return pci_register_driver(&serverworks_pci_driver); |
575 | } | 576 | } |
576 | 577 | ||
577 | |||
578 | static void __exit serverworks_exit(void) | 578 | static void __exit serverworks_exit(void) |
579 | { | 579 | { |
580 | pci_unregister_driver(&serverworks_pci_driver); | 580 | pci_unregister_driver(&serverworks_pci_driver); |
581 | } | 581 | } |
582 | 582 | ||
583 | |||
584 | MODULE_AUTHOR("Alan Cox"); | 583 | MODULE_AUTHOR("Alan Cox"); |
585 | MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6"); | 584 | MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6"); |
586 | MODULE_LICENSE("GPL"); | 585 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index c8b2e26db70..4a2b72b4be8 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c | |||
@@ -348,12 +348,13 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | static const struct pci_device_id sil680[] = { | 350 | static const struct pci_device_id sil680[] = { |
351 | { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), }, | 351 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), }, |
352 | { 0, }, | 352 | |
353 | { }, | ||
353 | }; | 354 | }; |
354 | 355 | ||
355 | static struct pci_driver sil680_pci_driver = { | 356 | static struct pci_driver sil680_pci_driver = { |
356 | .name = DRV_NAME, | 357 | .name = DRV_NAME, |
357 | .id_table = sil680, | 358 | .id_table = sil680, |
358 | .probe = sil680_init_one, | 359 | .probe = sil680_init_one, |
359 | .remove = ata_pci_remove_one | 360 | .remove = ata_pci_remove_one |
@@ -364,13 +365,11 @@ static int __init sil680_init(void) | |||
364 | return pci_register_driver(&sil680_pci_driver); | 365 | return pci_register_driver(&sil680_pci_driver); |
365 | } | 366 | } |
366 | 367 | ||
367 | |||
368 | static void __exit sil680_exit(void) | 368 | static void __exit sil680_exit(void) |
369 | { | 369 | { |
370 | pci_unregister_driver(&sil680_pci_driver); | 370 | pci_unregister_driver(&sil680_pci_driver); |
371 | } | 371 | } |
372 | 372 | ||
373 | |||
374 | MODULE_AUTHOR("Alan Cox"); | 373 | MODULE_AUTHOR("Alan Cox"); |
375 | MODULE_DESCRIPTION("low-level driver for SI680 PATA"); | 374 | MODULE_DESCRIPTION("low-level driver for SI680 PATA"); |
376 | MODULE_LICENSE("GPL"); | 375 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 17791e2785f..b9ffafb4198 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c | |||
@@ -988,8 +988,9 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
988 | } | 988 | } |
989 | 989 | ||
990 | static const struct pci_device_id sis_pci_tbl[] = { | 990 | static const struct pci_device_id sis_pci_tbl[] = { |
991 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x5513), }, /* SiS 5513 */ | 991 | { PCI_VDEVICE(SI, 0x5513), }, /* SiS 5513 */ |
992 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x5518), }, /* SiS 5518 */ | 992 | { PCI_VDEVICE(SI, 0x5518), }, /* SiS 5518 */ |
993 | |||
993 | { } | 994 | { } |
994 | }; | 995 | }; |
995 | 996 | ||
@@ -1010,7 +1011,6 @@ static void __exit sis_exit(void) | |||
1010 | pci_unregister_driver(&sis_pci_driver); | 1011 | pci_unregister_driver(&sis_pci_driver); |
1011 | } | 1012 | } |
1012 | 1013 | ||
1013 | |||
1014 | module_init(sis_init); | 1014 | module_init(sis_init); |
1015 | module_exit(sis_exit); | 1015 | module_exit(sis_exit); |
1016 | 1016 | ||
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 5b762acc568..08a6dc88676 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c | |||
@@ -351,9 +351,10 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
351 | return ata_pci_init_one(dev, port_info, 1); /* For now */ | 351 | return ata_pci_init_one(dev, port_info, 1); /* For now */ |
352 | } | 352 | } |
353 | 353 | ||
354 | static struct pci_device_id sl82c105[] = { | 354 | static const struct pci_device_id sl82c105[] = { |
355 | { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, | 355 | { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, |
356 | { 0, }, | 356 | |
357 | { }, | ||
357 | }; | 358 | }; |
358 | 359 | ||
359 | static struct pci_driver sl82c105_pci_driver = { | 360 | static struct pci_driver sl82c105_pci_driver = { |
@@ -368,13 +369,11 @@ static int __init sl82c105_init(void) | |||
368 | return pci_register_driver(&sl82c105_pci_driver); | 369 | return pci_register_driver(&sl82c105_pci_driver); |
369 | } | 370 | } |
370 | 371 | ||
371 | |||
372 | static void __exit sl82c105_exit(void) | 372 | static void __exit sl82c105_exit(void) |
373 | { | 373 | { |
374 | pci_unregister_driver(&sl82c105_pci_driver); | 374 | pci_unregister_driver(&sl82c105_pci_driver); |
375 | } | 375 | } |
376 | 376 | ||
377 | |||
378 | MODULE_AUTHOR("Alan Cox"); | 377 | MODULE_AUTHOR("Alan Cox"); |
379 | MODULE_DESCRIPTION("low-level driver for Sl82c105"); | 378 | MODULE_DESCRIPTION("low-level driver for Sl82c105"); |
380 | MODULE_LICENSE("GPL"); | 379 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index a954ed93a40..9640f80e8b0 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c | |||
@@ -248,13 +248,13 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
248 | } | 248 | } |
249 | 249 | ||
250 | static const struct pci_device_id triflex[] = { | 250 | static const struct pci_device_id triflex[] = { |
251 | { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, | 251 | { PCI_VDEVICE(COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE), }, |
252 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 252 | |
253 | { 0, }, | 253 | { }, |
254 | }; | 254 | }; |
255 | 255 | ||
256 | static struct pci_driver triflex_pci_driver = { | 256 | static struct pci_driver triflex_pci_driver = { |
257 | .name = DRV_NAME, | 257 | .name = DRV_NAME, |
258 | .id_table = triflex, | 258 | .id_table = triflex, |
259 | .probe = triflex_init_one, | 259 | .probe = triflex_init_one, |
260 | .remove = ata_pci_remove_one | 260 | .remove = ata_pci_remove_one |
@@ -265,13 +265,11 @@ static int __init triflex_init(void) | |||
265 | return pci_register_driver(&triflex_pci_driver); | 265 | return pci_register_driver(&triflex_pci_driver); |
266 | } | 266 | } |
267 | 267 | ||
268 | |||
269 | static void __exit triflex_exit(void) | 268 | static void __exit triflex_exit(void) |
270 | { | 269 | { |
271 | pci_unregister_driver(&triflex_pci_driver); | 270 | pci_unregister_driver(&triflex_pci_driver); |
272 | } | 271 | } |
273 | 272 | ||
274 | |||
275 | MODULE_AUTHOR("Alan Cox"); | 273 | MODULE_AUTHOR("Alan Cox"); |
276 | MODULE_DESCRIPTION("low-level driver for Compaq Triflex"); | 274 | MODULE_DESCRIPTION("low-level driver for Compaq Triflex"); |
277 | MODULE_LICENSE("GPL"); | 275 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 7b5dd2343b9..1e7be9eee9c 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -529,15 +529,16 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
529 | } | 529 | } |
530 | 530 | ||
531 | static const struct pci_device_id via[] = { | 531 | static const struct pci_device_id via[] = { |
532 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1), }, | 532 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), }, |
533 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1), }, | 533 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), }, |
534 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410), }, | 534 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), }, |
535 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), }, | 535 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), }, |
536 | { 0, }, | 536 | |
537 | { }, | ||
537 | }; | 538 | }; |
538 | 539 | ||
539 | static struct pci_driver via_pci_driver = { | 540 | static struct pci_driver via_pci_driver = { |
540 | .name = DRV_NAME, | 541 | .name = DRV_NAME, |
541 | .id_table = via, | 542 | .id_table = via, |
542 | .probe = via_init_one, | 543 | .probe = via_init_one, |
543 | .remove = ata_pci_remove_one | 544 | .remove = ata_pci_remove_one |
@@ -548,13 +549,11 @@ static int __init via_init(void) | |||
548 | return pci_register_driver(&via_pci_driver); | 549 | return pci_register_driver(&via_pci_driver); |
549 | } | 550 | } |
550 | 551 | ||
551 | |||
552 | static void __exit via_exit(void) | 552 | static void __exit via_exit(void) |
553 | { | 553 | { |
554 | pci_unregister_driver(&via_pci_driver); | 554 | pci_unregister_driver(&via_pci_driver); |
555 | } | 555 | } |
556 | 556 | ||
557 | |||
558 | MODULE_AUTHOR("Alan Cox"); | 557 | MODULE_AUTHOR("Alan Cox"); |
559 | MODULE_DESCRIPTION("low-level driver for VIA PATA"); | 558 | MODULE_DESCRIPTION("low-level driver for VIA PATA"); |
560 | MODULE_LICENSE("GPL"); | 559 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 0e23ecb77bc..81f3d219e70 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c | |||
@@ -192,8 +192,7 @@ static struct ata_port_info adma_port_info[] = { | |||
192 | }; | 192 | }; |
193 | 193 | ||
194 | static const struct pci_device_id adma_ata_pci_tbl[] = { | 194 | static const struct pci_device_id adma_ata_pci_tbl[] = { |
195 | { PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 195 | { PCI_VDEVICE(PDC, 0x1841), board_1841_idx }, |
196 | board_1841_idx }, | ||
197 | 196 | ||
198 | { } /* terminate list */ | 197 | { } /* terminate list */ |
199 | }; | 198 | }; |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index c01496df4a9..e6aa1a86d5c 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -533,19 +533,20 @@ static const struct ata_port_info mv_port_info[] = { | |||
533 | }; | 533 | }; |
534 | 534 | ||
535 | static const struct pci_device_id mv_pci_tbl[] = { | 535 | static const struct pci_device_id mv_pci_tbl[] = { |
536 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x}, | 536 | { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, |
537 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x}, | 537 | { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, |
538 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080}, | 538 | { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, |
539 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x}, | 539 | { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, |
540 | 540 | ||
541 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x}, | 541 | { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, |
542 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x}, | 542 | { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, |
543 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6042), 0, 0, chip_6042}, | 543 | { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, |
544 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x}, | 544 | { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, |
545 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x}, | 545 | { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, |
546 | 546 | ||
547 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x0241), 0, 0, chip_604x}, | 547 | { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, |
548 | {} /* terminate list */ | 548 | |
549 | { } /* terminate list */ | ||
549 | }; | 550 | }; |
550 | 551 | ||
551 | static struct pci_driver mv_pci_driver = { | 552 | static struct pci_driver mv_pci_driver = { |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 8cd730fe5dd..d09d20a1779 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -106,45 +106,32 @@ enum nv_host_type | |||
106 | }; | 106 | }; |
107 | 107 | ||
108 | static const struct pci_device_id nv_pci_tbl[] = { | 108 | static const struct pci_device_id nv_pci_tbl[] = { |
109 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, | 109 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA), NFORCE2 }, |
110 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 }, | 110 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA), NFORCE3 }, |
111 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, | 111 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2), NFORCE3 }, |
112 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 }, | 112 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA), CK804 }, |
113 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, | 113 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 }, |
114 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 }, | 114 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 }, |
115 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, | 115 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 }, |
116 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, | 116 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), GENERIC }, |
117 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, | 117 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), GENERIC }, |
118 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, | 118 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), GENERIC }, |
119 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, | 119 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), GENERIC }, |
120 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, | 120 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, |
121 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, | 121 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, |
122 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, | 122 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, |
123 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA, | 123 | { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, |
124 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | 124 | { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, |
125 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2, | 125 | { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, |
126 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | 126 | { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, |
127 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA, | ||
128 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
129 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2, | ||
130 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
131 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA, | ||
132 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
133 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2, | ||
134 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
135 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3, | ||
136 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
137 | { PCI_VENDOR_ID_NVIDIA, 0x045c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
138 | { PCI_VENDOR_ID_NVIDIA, 0x045d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
139 | { PCI_VENDOR_ID_NVIDIA, 0x045e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
140 | { PCI_VENDOR_ID_NVIDIA, 0x045f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, | ||
141 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, | 127 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, |
142 | PCI_ANY_ID, PCI_ANY_ID, | 128 | PCI_ANY_ID, PCI_ANY_ID, |
143 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, | 129 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, |
144 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, | 130 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, |
145 | PCI_ANY_ID, PCI_ANY_ID, | 131 | PCI_ANY_ID, PCI_ANY_ID, |
146 | PCI_CLASS_STORAGE_RAID<<8, 0xffff00, GENERIC }, | 132 | PCI_CLASS_STORAGE_RAID<<8, 0xffff00, GENERIC }, |
147 | { 0, } /* terminate list */ | 133 | |
134 | { } /* terminate list */ | ||
148 | }; | 135 | }; |
149 | 136 | ||
150 | static struct pci_driver nv_pci_driver = { | 137 | static struct pci_driver nv_pci_driver = { |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index d627812ea73..15c9437710f 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -234,48 +234,31 @@ static const struct ata_port_info pdc_port_info[] = { | |||
234 | }; | 234 | }; |
235 | 235 | ||
236 | static const struct pci_device_id pdc_ata_pci_tbl[] = { | 236 | static const struct pci_device_id pdc_ata_pci_tbl[] = { |
237 | { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 237 | { PCI_VDEVICE(PROMISE, 0x3371), board_2037x }, |
238 | board_2037x }, | 238 | { PCI_VDEVICE(PROMISE, 0x3570), board_2037x }, |
239 | { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 239 | { PCI_VDEVICE(PROMISE, 0x3571), board_2037x }, |
240 | board_2037x }, | 240 | { PCI_VDEVICE(PROMISE, 0x3373), board_2037x }, |
241 | { PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 241 | { PCI_VDEVICE(PROMISE, 0x3375), board_2037x }, |
242 | board_2037x }, | 242 | { PCI_VDEVICE(PROMISE, 0x3376), board_2037x }, |
243 | { PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 243 | { PCI_VDEVICE(PROMISE, 0x3574), board_2057x }, |
244 | board_2037x }, | 244 | { PCI_VDEVICE(PROMISE, 0x3d75), board_2057x }, |
245 | { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 245 | { PCI_VDEVICE(PROMISE, 0x3d73), board_2037x }, |
246 | board_2037x }, | 246 | |
247 | { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 247 | { PCI_VDEVICE(PROMISE, 0x3318), board_20319 }, |
248 | board_2037x }, | 248 | { PCI_VDEVICE(PROMISE, 0x3319), board_20319 }, |
249 | { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 249 | { PCI_VDEVICE(PROMISE, 0x3515), board_20319 }, |
250 | board_2057x }, | 250 | { PCI_VDEVICE(PROMISE, 0x3519), board_20319 }, |
251 | { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 251 | { PCI_VDEVICE(PROMISE, 0x3d17), board_20319 }, |
252 | board_2057x }, | 252 | { PCI_VDEVICE(PROMISE, 0x3d18), board_40518 }, |
253 | { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 253 | |
254 | board_2037x }, | 254 | { PCI_VDEVICE(PROMISE, 0x6629), board_20619 }, |
255 | |||
256 | { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
257 | board_20319 }, | ||
258 | { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
259 | board_20319 }, | ||
260 | { PCI_VENDOR_ID_PROMISE, 0x3515, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
261 | board_20319 }, | ||
262 | { PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
263 | board_20319 }, | ||
264 | { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
265 | board_20319 }, | ||
266 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
267 | board_40518 }, | ||
268 | |||
269 | { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
270 | board_20619 }, | ||
271 | 255 | ||
272 | /* TODO: remove all associated board_20771 code, as it completely | 256 | /* TODO: remove all associated board_20771 code, as it completely |
273 | * duplicates board_2037x code, unless reason for separation can be | 257 | * duplicates board_2037x code, unless reason for separation can be |
274 | * divined. | 258 | * divined. |
275 | */ | 259 | */ |
276 | #if 0 | 260 | #if 0 |
277 | { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 261 | { PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, |
278 | board_20771 }, | ||
279 | #endif | 262 | #endif |
280 | 263 | ||
281 | { } /* terminate list */ | 264 | { } /* terminate list */ |
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index fa29dfe2a7b..7f6cc3c07de 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -185,8 +185,7 @@ static const struct ata_port_info qs_port_info[] = { | |||
185 | }; | 185 | }; |
186 | 186 | ||
187 | static const struct pci_device_id qs_ata_pci_tbl[] = { | 187 | static const struct pci_device_id qs_ata_pci_tbl[] = { |
188 | { PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 188 | { PCI_VDEVICE(PDC, 0x2068), board_2068_idx }, |
189 | board_2068_idx }, | ||
190 | 189 | ||
191 | { } /* terminate list */ | 190 | { } /* terminate list */ |
192 | }; | 191 | }; |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index c63dbabc0cd..3d9fa1cc834 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -123,13 +123,14 @@ static void sil_thaw(struct ata_port *ap); | |||
123 | 123 | ||
124 | 124 | ||
125 | static const struct pci_device_id sil_pci_tbl[] = { | 125 | static const struct pci_device_id sil_pci_tbl[] = { |
126 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 126 | { PCI_VDEVICE(CMD, 0x3112), sil_3112 }, |
127 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 127 | { PCI_VDEVICE(CMD, 0x0240), sil_3112 }, |
128 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, | 128 | { PCI_VDEVICE(CMD, 0x3512), sil_3512 }, |
129 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 129 | { PCI_VDEVICE(CMD, 0x3114), sil_3114 }, |
130 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 130 | { PCI_VDEVICE(ATI, 0x436e), sil_3112 }, |
131 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, | 131 | { PCI_VDEVICE(ATI, 0x4379), sil_3112_no_sata_irq }, |
132 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, | 132 | { PCI_VDEVICE(ATI, 0x437a), sil_3112_no_sata_irq }, |
133 | |||
133 | { } /* terminate list */ | 134 | { } /* terminate list */ |
134 | }; | 135 | }; |
135 | 136 | ||
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 39cb07baeba..a951f40c2f2 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -344,11 +344,12 @@ static int sil24_pci_device_resume(struct pci_dev *pdev); | |||
344 | #endif | 344 | #endif |
345 | 345 | ||
346 | static const struct pci_device_id sil24_pci_tbl[] = { | 346 | static const struct pci_device_id sil24_pci_tbl[] = { |
347 | { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 }, | 347 | { PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 }, |
348 | { 0x8086, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 }, | 348 | { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 }, |
349 | { 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 }, | 349 | { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 }, |
350 | { 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 }, | 350 | { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 }, |
351 | { 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 }, | 351 | { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 }, |
352 | |||
352 | { } /* terminate list */ | 353 | { } /* terminate list */ |
353 | }; | 354 | }; |
354 | 355 | ||
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 18d49fff8dc..0738f52463a 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -67,13 +67,13 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); | |||
67 | static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 67 | static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
68 | 68 | ||
69 | static const struct pci_device_id sis_pci_tbl[] = { | 69 | static const struct pci_device_id sis_pci_tbl[] = { |
70 | { PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, | 70 | { PCI_VDEVICE(SI, 0x180), sis_180 }, |
71 | { PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, | 71 | { PCI_VDEVICE(SI, 0x181), sis_180 }, |
72 | { PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, | 72 | { PCI_VDEVICE(SI, 0x182), sis_180 }, |
73 | |||
73 | { } /* terminate list */ | 74 | { } /* terminate list */ |
74 | }; | 75 | }; |
75 | 76 | ||
76 | |||
77 | static struct pci_driver sis_pci_driver = { | 77 | static struct pci_driver sis_pci_driver = { |
78 | .name = DRV_NAME, | 78 | .name = DRV_NAME, |
79 | .id_table = sis_pci_tbl, | 79 | .id_table = sis_pci_tbl, |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index d6d6658d832..84025a2fd5b 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -469,15 +469,15 @@ err_out: | |||
469 | * controller | 469 | * controller |
470 | * */ | 470 | * */ |
471 | static const struct pci_device_id k2_sata_pci_tbl[] = { | 471 | static const struct pci_device_id k2_sata_pci_tbl[] = { |
472 | { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | 472 | { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 }, |
473 | { 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | 473 | { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 }, |
474 | { 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | 474 | { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 }, |
475 | { 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | 475 | { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 }, |
476 | { 0x1166, 0x024b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | 476 | { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 }, |
477 | |||
477 | { } | 478 | { } |
478 | }; | 479 | }; |
479 | 480 | ||
480 | |||
481 | static struct pci_driver k2_sata_pci_driver = { | 481 | static struct pci_driver k2_sata_pci_driver = { |
482 | .name = DRV_NAME, | 482 | .name = DRV_NAME, |
483 | .id_table = k2_sata_pci_tbl, | 483 | .id_table = k2_sata_pci_tbl, |
@@ -485,19 +485,16 @@ static struct pci_driver k2_sata_pci_driver = { | |||
485 | .remove = ata_pci_remove_one, | 485 | .remove = ata_pci_remove_one, |
486 | }; | 486 | }; |
487 | 487 | ||
488 | |||
489 | static int __init k2_sata_init(void) | 488 | static int __init k2_sata_init(void) |
490 | { | 489 | { |
491 | return pci_register_driver(&k2_sata_pci_driver); | 490 | return pci_register_driver(&k2_sata_pci_driver); |
492 | } | 491 | } |
493 | 492 | ||
494 | |||
495 | static void __exit k2_sata_exit(void) | 493 | static void __exit k2_sata_exit(void) |
496 | { | 494 | { |
497 | pci_unregister_driver(&k2_sata_pci_driver); | 495 | pci_unregister_driver(&k2_sata_pci_driver); |
498 | } | 496 | } |
499 | 497 | ||
500 | |||
501 | MODULE_AUTHOR("Benjamin Herrenschmidt"); | 498 | MODULE_AUTHOR("Benjamin Herrenschmidt"); |
502 | MODULE_DESCRIPTION("low-level driver for K2 SATA controller"); | 499 | MODULE_DESCRIPTION("low-level driver for K2 SATA controller"); |
503 | MODULE_LICENSE("GPL"); | 500 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 091867e10ea..8c74f2ff434 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c | |||
@@ -230,12 +230,11 @@ static const struct ata_port_info pdc_port_info[] = { | |||
230 | }; | 230 | }; |
231 | 231 | ||
232 | static const struct pci_device_id pdc_sata_pci_tbl[] = { | 232 | static const struct pci_device_id pdc_sata_pci_tbl[] = { |
233 | { PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 233 | { PCI_VDEVICE(PROMISE, 0x6622), board_20621 }, |
234 | board_20621 }, | 234 | |
235 | { } /* terminate list */ | 235 | { } /* terminate list */ |
236 | }; | 236 | }; |
237 | 237 | ||
238 | |||
239 | static struct pci_driver pdc_sata_pci_driver = { | 238 | static struct pci_driver pdc_sata_pci_driver = { |
240 | .name = DRV_NAME, | 239 | .name = DRV_NAME, |
241 | .id_table = pdc_sata_pci_tbl, | 240 | .id_table = pdc_sata_pci_tbl, |
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index dd76f37be18..5c603ca3a50 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -61,13 +61,13 @@ static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); | |||
61 | static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 61 | static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
62 | 62 | ||
63 | static const struct pci_device_id uli_pci_tbl[] = { | 63 | static const struct pci_device_id uli_pci_tbl[] = { |
64 | { PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 }, | 64 | { PCI_VDEVICE(AL, 0x5289), uli_5289 }, |
65 | { PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 }, | 65 | { PCI_VDEVICE(AL, 0x5287), uli_5287 }, |
66 | { PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 }, | 66 | { PCI_VDEVICE(AL, 0x5281), uli_5281 }, |
67 | |||
67 | { } /* terminate list */ | 68 | { } /* terminate list */ |
68 | }; | 69 | }; |
69 | 70 | ||
70 | |||
71 | static struct pci_driver uli_pci_driver = { | 71 | static struct pci_driver uli_pci_driver = { |
72 | .name = DRV_NAME, | 72 | .name = DRV_NAME, |
73 | .id_table = uli_pci_tbl, | 73 | .id_table = uli_pci_tbl, |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index a72a2389a11..f4455a1efe2 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -77,9 +77,9 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
77 | static void vt6420_error_handler(struct ata_port *ap); | 77 | static void vt6420_error_handler(struct ata_port *ap); |
78 | 78 | ||
79 | static const struct pci_device_id svia_pci_tbl[] = { | 79 | static const struct pci_device_id svia_pci_tbl[] = { |
80 | { 0x1106, 0x0591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, | 80 | { PCI_VDEVICE(VIA, 0x0591), vt6420 }, |
81 | { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, | 81 | { PCI_VDEVICE(VIA, 0x3149), vt6420 }, |
82 | { 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 }, | 82 | { PCI_VDEVICE(VIA, 0x3249), vt6421 }, |
83 | 83 | ||
84 | { } /* terminate list */ | 84 | { } /* terminate list */ |
85 | }; | 85 | }; |
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index d0d92f33de5..273d88fcf98 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -442,16 +442,15 @@ err_out: | |||
442 | return rc; | 442 | return rc; |
443 | } | 443 | } |
444 | 444 | ||
445 | |||
446 | static const struct pci_device_id vsc_sata_pci_tbl[] = { | 445 | static const struct pci_device_id vsc_sata_pci_tbl[] = { |
447 | { PCI_VENDOR_ID_VITESSE, 0x7174, | 446 | { PCI_VENDOR_ID_VITESSE, 0x7174, |
448 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, | 447 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, |
449 | { PCI_VENDOR_ID_INTEL, 0x3200, | 448 | { PCI_VENDOR_ID_INTEL, 0x3200, |
450 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, | 449 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, |
450 | |||
451 | { } /* terminate list */ | 451 | { } /* terminate list */ |
452 | }; | 452 | }; |
453 | 453 | ||
454 | |||
455 | static struct pci_driver vsc_sata_pci_driver = { | 454 | static struct pci_driver vsc_sata_pci_driver = { |
456 | .name = DRV_NAME, | 455 | .name = DRV_NAME, |
457 | .id_table = vsc_sata_pci_tbl, | 456 | .id_table = vsc_sata_pci_tbl, |
@@ -459,19 +458,16 @@ static struct pci_driver vsc_sata_pci_driver = { | |||
459 | .remove = ata_pci_remove_one, | 458 | .remove = ata_pci_remove_one, |
460 | }; | 459 | }; |
461 | 460 | ||
462 | |||
463 | static int __init vsc_sata_init(void) | 461 | static int __init vsc_sata_init(void) |
464 | { | 462 | { |
465 | return pci_register_driver(&vsc_sata_pci_driver); | 463 | return pci_register_driver(&vsc_sata_pci_driver); |
466 | } | 464 | } |
467 | 465 | ||
468 | |||
469 | static void __exit vsc_sata_exit(void) | 466 | static void __exit vsc_sata_exit(void) |
470 | { | 467 | { |
471 | pci_unregister_driver(&vsc_sata_pci_driver); | 468 | pci_unregister_driver(&vsc_sata_pci_driver); |
472 | } | 469 | } |
473 | 470 | ||
474 | |||
475 | MODULE_AUTHOR("Jeremy Higdon"); | 471 | MODULE_AUTHOR("Jeremy Higdon"); |
476 | MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller"); | 472 | MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller"); |
477 | MODULE_LICENSE("GPL"); | 473 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index a6b2aa67c9b..f2904f67af4 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -62,6 +62,8 @@ | |||
62 | 62 | ||
63 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
64 | 64 | ||
65 | #define DRIVER_NAME "pktcdvd" | ||
66 | |||
65 | #if PACKET_DEBUG | 67 | #if PACKET_DEBUG |
66 | #define DPRINTK(fmt, args...) printk(KERN_NOTICE fmt, ##args) | 68 | #define DPRINTK(fmt, args...) printk(KERN_NOTICE fmt, ##args) |
67 | #else | 69 | #else |
@@ -80,7 +82,7 @@ | |||
80 | 82 | ||
81 | static struct pktcdvd_device *pkt_devs[MAX_WRITERS]; | 83 | static struct pktcdvd_device *pkt_devs[MAX_WRITERS]; |
82 | static struct proc_dir_entry *pkt_proc; | 84 | static struct proc_dir_entry *pkt_proc; |
83 | static int pkt_major; | 85 | static int pktdev_major; |
84 | static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */ | 86 | static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */ |
85 | static mempool_t *psd_pool; | 87 | static mempool_t *psd_pool; |
86 | 88 | ||
@@ -89,7 +91,7 @@ static void pkt_bio_finished(struct pktcdvd_device *pd) | |||
89 | { | 91 | { |
90 | BUG_ON(atomic_read(&pd->cdrw.pending_bios) <= 0); | 92 | BUG_ON(atomic_read(&pd->cdrw.pending_bios) <= 0); |
91 | if (atomic_dec_and_test(&pd->cdrw.pending_bios)) { | 93 | if (atomic_dec_and_test(&pd->cdrw.pending_bios)) { |
92 | VPRINTK("pktcdvd: queue empty\n"); | 94 | VPRINTK(DRIVER_NAME": queue empty\n"); |
93 | atomic_set(&pd->iosched.attention, 1); | 95 | atomic_set(&pd->iosched.attention, 1); |
94 | wake_up(&pd->wqueue); | 96 | wake_up(&pd->wqueue); |
95 | } | 97 | } |
@@ -400,7 +402,7 @@ static void pkt_dump_sense(struct packet_command *cgc) | |||
400 | int i; | 402 | int i; |
401 | struct request_sense *sense = cgc->sense; | 403 | struct request_sense *sense = cgc->sense; |
402 | 404 | ||
403 | printk("pktcdvd:"); | 405 | printk(DRIVER_NAME":"); |
404 | for (i = 0; i < CDROM_PACKET_SIZE; i++) | 406 | for (i = 0; i < CDROM_PACKET_SIZE; i++) |
405 | printk(" %02x", cgc->cmd[i]); | 407 | printk(" %02x", cgc->cmd[i]); |
406 | printk(" - "); | 408 | printk(" - "); |
@@ -528,7 +530,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
528 | need_write_seek = 0; | 530 | need_write_seek = 0; |
529 | if (need_write_seek && reads_queued) { | 531 | if (need_write_seek && reads_queued) { |
530 | if (atomic_read(&pd->cdrw.pending_bios) > 0) { | 532 | if (atomic_read(&pd->cdrw.pending_bios) > 0) { |
531 | VPRINTK("pktcdvd: write, waiting\n"); | 533 | VPRINTK(DRIVER_NAME": write, waiting\n"); |
532 | break; | 534 | break; |
533 | } | 535 | } |
534 | pkt_flush_cache(pd); | 536 | pkt_flush_cache(pd); |
@@ -537,7 +539,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
537 | } else { | 539 | } else { |
538 | if (!reads_queued && writes_queued) { | 540 | if (!reads_queued && writes_queued) { |
539 | if (atomic_read(&pd->cdrw.pending_bios) > 0) { | 541 | if (atomic_read(&pd->cdrw.pending_bios) > 0) { |
540 | VPRINTK("pktcdvd: read, waiting\n"); | 542 | VPRINTK(DRIVER_NAME": read, waiting\n"); |
541 | break; | 543 | break; |
542 | } | 544 | } |
543 | pd->iosched.writing = 1; | 545 | pd->iosched.writing = 1; |
@@ -600,7 +602,7 @@ static int pkt_set_segment_merging(struct pktcdvd_device *pd, request_queue_t *q | |||
600 | set_bit(PACKET_MERGE_SEGS, &pd->flags); | 602 | set_bit(PACKET_MERGE_SEGS, &pd->flags); |
601 | return 0; | 603 | return 0; |
602 | } else { | 604 | } else { |
603 | printk("pktcdvd: cdrom max_phys_segments too small\n"); | 605 | printk(DRIVER_NAME": cdrom max_phys_segments too small\n"); |
604 | return -EIO; | 606 | return -EIO; |
605 | } | 607 | } |
606 | } | 608 | } |
@@ -1049,7 +1051,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1049 | for (f = 0; f < pkt->frames; f++) | 1051 | for (f = 0; f < pkt->frames; f++) |
1050 | if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset)) | 1052 | if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset)) |
1051 | BUG(); | 1053 | BUG(); |
1052 | VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); | 1054 | VPRINTK(DRIVER_NAME": vcnt=%d\n", pkt->w_bio->bi_vcnt); |
1053 | 1055 | ||
1054 | atomic_set(&pkt->io_wait, 1); | 1056 | atomic_set(&pkt->io_wait, 1); |
1055 | pkt->w_bio->bi_rw = WRITE; | 1057 | pkt->w_bio->bi_rw = WRITE; |
@@ -1286,7 +1288,7 @@ work_to_do: | |||
1286 | 1288 | ||
1287 | static void pkt_print_settings(struct pktcdvd_device *pd) | 1289 | static void pkt_print_settings(struct pktcdvd_device *pd) |
1288 | { | 1290 | { |
1289 | printk("pktcdvd: %s packets, ", pd->settings.fp ? "Fixed" : "Variable"); | 1291 | printk(DRIVER_NAME": %s packets, ", pd->settings.fp ? "Fixed" : "Variable"); |
1290 | printk("%u blocks, ", pd->settings.size >> 2); | 1292 | printk("%u blocks, ", pd->settings.size >> 2); |
1291 | printk("Mode-%c disc\n", pd->settings.block_mode == 8 ? '1' : '2'); | 1293 | printk("Mode-%c disc\n", pd->settings.block_mode == 8 ? '1' : '2'); |
1292 | } | 1294 | } |
@@ -1471,7 +1473,7 @@ static int pkt_set_write_settings(struct pktcdvd_device *pd) | |||
1471 | /* | 1473 | /* |
1472 | * paranoia | 1474 | * paranoia |
1473 | */ | 1475 | */ |
1474 | printk("pktcdvd: write mode wrong %d\n", wp->data_block_type); | 1476 | printk(DRIVER_NAME": write mode wrong %d\n", wp->data_block_type); |
1475 | return 1; | 1477 | return 1; |
1476 | } | 1478 | } |
1477 | wp->packet_size = cpu_to_be32(pd->settings.size >> 2); | 1479 | wp->packet_size = cpu_to_be32(pd->settings.size >> 2); |
@@ -1515,7 +1517,7 @@ static int pkt_writable_track(struct pktcdvd_device *pd, track_information *ti) | |||
1515 | if (ti->rt == 1 && ti->blank == 0) | 1517 | if (ti->rt == 1 && ti->blank == 0) |
1516 | return 1; | 1518 | return 1; |
1517 | 1519 | ||
1518 | printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet); | 1520 | printk(DRIVER_NAME": bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet); |
1519 | return 0; | 1521 | return 0; |
1520 | } | 1522 | } |
1521 | 1523 | ||
@@ -1533,7 +1535,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di) | |||
1533 | case 0x12: /* DVD-RAM */ | 1535 | case 0x12: /* DVD-RAM */ |
1534 | return 1; | 1536 | return 1; |
1535 | default: | 1537 | default: |
1536 | VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); | 1538 | VPRINTK(DRIVER_NAME": Wrong disc profile (%x)\n", pd->mmc3_profile); |
1537 | return 0; | 1539 | return 0; |
1538 | } | 1540 | } |
1539 | 1541 | ||
@@ -1542,22 +1544,22 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di) | |||
1542 | * but i'm not sure, should we leave this to user apps? probably. | 1544 | * but i'm not sure, should we leave this to user apps? probably. |
1543 | */ | 1545 | */ |
1544 | if (di->disc_type == 0xff) { | 1546 | if (di->disc_type == 0xff) { |
1545 | printk("pktcdvd: Unknown disc. No track?\n"); | 1547 | printk(DRIVER_NAME": Unknown disc. No track?\n"); |
1546 | return 0; | 1548 | return 0; |
1547 | } | 1549 | } |
1548 | 1550 | ||
1549 | if (di->disc_type != 0x20 && di->disc_type != 0) { | 1551 | if (di->disc_type != 0x20 && di->disc_type != 0) { |
1550 | printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type); | 1552 | printk(DRIVER_NAME": Wrong disc type (%x)\n", di->disc_type); |
1551 | return 0; | 1553 | return 0; |
1552 | } | 1554 | } |
1553 | 1555 | ||
1554 | if (di->erasable == 0) { | 1556 | if (di->erasable == 0) { |
1555 | printk("pktcdvd: Disc not erasable\n"); | 1557 | printk(DRIVER_NAME": Disc not erasable\n"); |
1556 | return 0; | 1558 | return 0; |
1557 | } | 1559 | } |
1558 | 1560 | ||
1559 | if (di->border_status == PACKET_SESSION_RESERVED) { | 1561 | if (di->border_status == PACKET_SESSION_RESERVED) { |
1560 | printk("pktcdvd: Can't write to last track (reserved)\n"); | 1562 | printk(DRIVER_NAME": Can't write to last track (reserved)\n"); |
1561 | return 0; | 1563 | return 0; |
1562 | } | 1564 | } |
1563 | 1565 | ||
@@ -1593,12 +1595,12 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1593 | 1595 | ||
1594 | track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */ | 1596 | track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */ |
1595 | if ((ret = pkt_get_track_info(pd, track, 1, &ti))) { | 1597 | if ((ret = pkt_get_track_info(pd, track, 1, &ti))) { |
1596 | printk("pktcdvd: failed get_track\n"); | 1598 | printk(DRIVER_NAME": failed get_track\n"); |
1597 | return ret; | 1599 | return ret; |
1598 | } | 1600 | } |
1599 | 1601 | ||
1600 | if (!pkt_writable_track(pd, &ti)) { | 1602 | if (!pkt_writable_track(pd, &ti)) { |
1601 | printk("pktcdvd: can't write to this track\n"); | 1603 | printk(DRIVER_NAME": can't write to this track\n"); |
1602 | return -EROFS; | 1604 | return -EROFS; |
1603 | } | 1605 | } |
1604 | 1606 | ||
@@ -1608,11 +1610,11 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1608 | */ | 1610 | */ |
1609 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; | 1611 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; |
1610 | if (pd->settings.size == 0) { | 1612 | if (pd->settings.size == 0) { |
1611 | printk("pktcdvd: detected zero packet size!\n"); | 1613 | printk(DRIVER_NAME": detected zero packet size!\n"); |
1612 | return -ENXIO; | 1614 | return -ENXIO; |
1613 | } | 1615 | } |
1614 | if (pd->settings.size > PACKET_MAX_SECTORS) { | 1616 | if (pd->settings.size > PACKET_MAX_SECTORS) { |
1615 | printk("pktcdvd: packet size is too big\n"); | 1617 | printk(DRIVER_NAME": packet size is too big\n"); |
1616 | return -EROFS; | 1618 | return -EROFS; |
1617 | } | 1619 | } |
1618 | pd->settings.fp = ti.fp; | 1620 | pd->settings.fp = ti.fp; |
@@ -1654,7 +1656,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1654 | pd->settings.block_mode = PACKET_BLOCK_MODE2; | 1656 | pd->settings.block_mode = PACKET_BLOCK_MODE2; |
1655 | break; | 1657 | break; |
1656 | default: | 1658 | default: |
1657 | printk("pktcdvd: unknown data mode\n"); | 1659 | printk(DRIVER_NAME": unknown data mode\n"); |
1658 | return -EROFS; | 1660 | return -EROFS; |
1659 | } | 1661 | } |
1660 | return 0; | 1662 | return 0; |
@@ -1688,10 +1690,10 @@ static int pkt_write_caching(struct pktcdvd_device *pd, int set) | |||
1688 | cgc.buflen = cgc.cmd[8] = 2 + ((buf[0] << 8) | (buf[1] & 0xff)); | 1690 | cgc.buflen = cgc.cmd[8] = 2 + ((buf[0] << 8) | (buf[1] & 0xff)); |
1689 | ret = pkt_mode_select(pd, &cgc); | 1691 | ret = pkt_mode_select(pd, &cgc); |
1690 | if (ret) { | 1692 | if (ret) { |
1691 | printk("pktcdvd: write caching control failed\n"); | 1693 | printk(DRIVER_NAME": write caching control failed\n"); |
1692 | pkt_dump_sense(&cgc); | 1694 | pkt_dump_sense(&cgc); |
1693 | } else if (!ret && set) | 1695 | } else if (!ret && set) |
1694 | printk("pktcdvd: enabled write caching on %s\n", pd->name); | 1696 | printk(DRIVER_NAME": enabled write caching on %s\n", pd->name); |
1695 | return ret; | 1697 | return ret; |
1696 | } | 1698 | } |
1697 | 1699 | ||
@@ -1805,11 +1807,11 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) | |||
1805 | } | 1807 | } |
1806 | 1808 | ||
1807 | if (!buf[6] & 0x40) { | 1809 | if (!buf[6] & 0x40) { |
1808 | printk("pktcdvd: Disc type is not CD-RW\n"); | 1810 | printk(DRIVER_NAME": Disc type is not CD-RW\n"); |
1809 | return 1; | 1811 | return 1; |
1810 | } | 1812 | } |
1811 | if (!buf[6] & 0x4) { | 1813 | if (!buf[6] & 0x4) { |
1812 | printk("pktcdvd: A1 values on media are not valid, maybe not CDRW?\n"); | 1814 | printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n"); |
1813 | return 1; | 1815 | return 1; |
1814 | } | 1816 | } |
1815 | 1817 | ||
@@ -1829,14 +1831,14 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) | |||
1829 | *speed = us_clv_to_speed[sp]; | 1831 | *speed = us_clv_to_speed[sp]; |
1830 | break; | 1832 | break; |
1831 | default: | 1833 | default: |
1832 | printk("pktcdvd: Unknown disc sub-type %d\n",st); | 1834 | printk(DRIVER_NAME": Unknown disc sub-type %d\n",st); |
1833 | return 1; | 1835 | return 1; |
1834 | } | 1836 | } |
1835 | if (*speed) { | 1837 | if (*speed) { |
1836 | printk("pktcdvd: Max. media speed: %d\n",*speed); | 1838 | printk(DRIVER_NAME": Max. media speed: %d\n",*speed); |
1837 | return 0; | 1839 | return 0; |
1838 | } else { | 1840 | } else { |
1839 | printk("pktcdvd: Unknown speed %d for sub-type %d\n",sp,st); | 1841 | printk(DRIVER_NAME": Unknown speed %d for sub-type %d\n",sp,st); |
1840 | return 1; | 1842 | return 1; |
1841 | } | 1843 | } |
1842 | } | 1844 | } |
@@ -1847,7 +1849,7 @@ static int pkt_perform_opc(struct pktcdvd_device *pd) | |||
1847 | struct request_sense sense; | 1849 | struct request_sense sense; |
1848 | int ret; | 1850 | int ret; |
1849 | 1851 | ||
1850 | VPRINTK("pktcdvd: Performing OPC\n"); | 1852 | VPRINTK(DRIVER_NAME": Performing OPC\n"); |
1851 | 1853 | ||
1852 | init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE); | 1854 | init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE); |
1853 | cgc.sense = &sense; | 1855 | cgc.sense = &sense; |
@@ -1865,12 +1867,12 @@ static int pkt_open_write(struct pktcdvd_device *pd) | |||
1865 | unsigned int write_speed, media_write_speed, read_speed; | 1867 | unsigned int write_speed, media_write_speed, read_speed; |
1866 | 1868 | ||
1867 | if ((ret = pkt_probe_settings(pd))) { | 1869 | if ((ret = pkt_probe_settings(pd))) { |
1868 | VPRINTK("pktcdvd: %s failed probe\n", pd->name); | 1870 | VPRINTK(DRIVER_NAME": %s failed probe\n", pd->name); |
1869 | return ret; | 1871 | return ret; |
1870 | } | 1872 | } |
1871 | 1873 | ||
1872 | if ((ret = pkt_set_write_settings(pd))) { | 1874 | if ((ret = pkt_set_write_settings(pd))) { |
1873 | DPRINTK("pktcdvd: %s failed saving write settings\n", pd->name); | 1875 | DPRINTK(DRIVER_NAME": %s failed saving write settings\n", pd->name); |
1874 | return -EIO; | 1876 | return -EIO; |
1875 | } | 1877 | } |
1876 | 1878 | ||
@@ -1882,26 +1884,26 @@ static int pkt_open_write(struct pktcdvd_device *pd) | |||
1882 | case 0x13: /* DVD-RW */ | 1884 | case 0x13: /* DVD-RW */ |
1883 | case 0x1a: /* DVD+RW */ | 1885 | case 0x1a: /* DVD+RW */ |
1884 | case 0x12: /* DVD-RAM */ | 1886 | case 0x12: /* DVD-RAM */ |
1885 | DPRINTK("pktcdvd: write speed %ukB/s\n", write_speed); | 1887 | DPRINTK(DRIVER_NAME": write speed %ukB/s\n", write_speed); |
1886 | break; | 1888 | break; |
1887 | default: | 1889 | default: |
1888 | if ((ret = pkt_media_speed(pd, &media_write_speed))) | 1890 | if ((ret = pkt_media_speed(pd, &media_write_speed))) |
1889 | media_write_speed = 16; | 1891 | media_write_speed = 16; |
1890 | write_speed = min(write_speed, media_write_speed * 177); | 1892 | write_speed = min(write_speed, media_write_speed * 177); |
1891 | DPRINTK("pktcdvd: write speed %ux\n", write_speed / 176); | 1893 | DPRINTK(DRIVER_NAME": write speed %ux\n", write_speed / 176); |
1892 | break; | 1894 | break; |
1893 | } | 1895 | } |
1894 | read_speed = write_speed; | 1896 | read_speed = write_speed; |
1895 | 1897 | ||
1896 | if ((ret = pkt_set_speed(pd, write_speed, read_speed))) { | 1898 | if ((ret = pkt_set_speed(pd, write_speed, read_speed))) { |
1897 | DPRINTK("pktcdvd: %s couldn't set write speed\n", pd->name); | 1899 | DPRINTK(DRIVER_NAME": %s couldn't set write speed\n", pd->name); |
1898 | return -EIO; | 1900 | return -EIO; |
1899 | } | 1901 | } |
1900 | pd->write_speed = write_speed; | 1902 | pd->write_speed = write_speed; |
1901 | pd->read_speed = read_speed; | 1903 | pd->read_speed = read_speed; |
1902 | 1904 | ||
1903 | if ((ret = pkt_perform_opc(pd))) { | 1905 | if ((ret = pkt_perform_opc(pd))) { |
1904 | DPRINTK("pktcdvd: %s Optimum Power Calibration failed\n", pd->name); | 1906 | DPRINTK(DRIVER_NAME": %s Optimum Power Calibration failed\n", pd->name); |
1905 | } | 1907 | } |
1906 | 1908 | ||
1907 | return 0; | 1909 | return 0; |
@@ -1929,7 +1931,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) | |||
1929 | goto out_putdev; | 1931 | goto out_putdev; |
1930 | 1932 | ||
1931 | if ((ret = pkt_get_last_written(pd, &lba))) { | 1933 | if ((ret = pkt_get_last_written(pd, &lba))) { |
1932 | printk("pktcdvd: pkt_get_last_written failed\n"); | 1934 | printk(DRIVER_NAME": pkt_get_last_written failed\n"); |
1933 | goto out_unclaim; | 1935 | goto out_unclaim; |
1934 | } | 1936 | } |
1935 | 1937 | ||
@@ -1959,11 +1961,11 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) | |||
1959 | 1961 | ||
1960 | if (write) { | 1962 | if (write) { |
1961 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { | 1963 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { |
1962 | printk("pktcdvd: not enough memory for buffers\n"); | 1964 | printk(DRIVER_NAME": not enough memory for buffers\n"); |
1963 | ret = -ENOMEM; | 1965 | ret = -ENOMEM; |
1964 | goto out_unclaim; | 1966 | goto out_unclaim; |
1965 | } | 1967 | } |
1966 | printk("pktcdvd: %lukB available on disc\n", lba << 1); | 1968 | printk(DRIVER_NAME": %lukB available on disc\n", lba << 1); |
1967 | } | 1969 | } |
1968 | 1970 | ||
1969 | return 0; | 1971 | return 0; |
@@ -1983,7 +1985,7 @@ out: | |||
1983 | static void pkt_release_dev(struct pktcdvd_device *pd, int flush) | 1985 | static void pkt_release_dev(struct pktcdvd_device *pd, int flush) |
1984 | { | 1986 | { |
1985 | if (flush && pkt_flush_cache(pd)) | 1987 | if (flush && pkt_flush_cache(pd)) |
1986 | DPRINTK("pktcdvd: %s not flushing cache\n", pd->name); | 1988 | DPRINTK(DRIVER_NAME": %s not flushing cache\n", pd->name); |
1987 | 1989 | ||
1988 | pkt_lock_door(pd, 0); | 1990 | pkt_lock_door(pd, 0); |
1989 | 1991 | ||
@@ -2006,7 +2008,7 @@ static int pkt_open(struct inode *inode, struct file *file) | |||
2006 | struct pktcdvd_device *pd = NULL; | 2008 | struct pktcdvd_device *pd = NULL; |
2007 | int ret; | 2009 | int ret; |
2008 | 2010 | ||
2009 | VPRINTK("pktcdvd: entering open\n"); | 2011 | VPRINTK(DRIVER_NAME": entering open\n"); |
2010 | 2012 | ||
2011 | mutex_lock(&ctl_mutex); | 2013 | mutex_lock(&ctl_mutex); |
2012 | pd = pkt_find_dev_from_minor(iminor(inode)); | 2014 | pd = pkt_find_dev_from_minor(iminor(inode)); |
@@ -2040,7 +2042,7 @@ static int pkt_open(struct inode *inode, struct file *file) | |||
2040 | out_dec: | 2042 | out_dec: |
2041 | pd->refcnt--; | 2043 | pd->refcnt--; |
2042 | out: | 2044 | out: |
2043 | VPRINTK("pktcdvd: failed open (%d)\n", ret); | 2045 | VPRINTK(DRIVER_NAME": failed open (%d)\n", ret); |
2044 | mutex_unlock(&ctl_mutex); | 2046 | mutex_unlock(&ctl_mutex); |
2045 | return ret; | 2047 | return ret; |
2046 | } | 2048 | } |
@@ -2088,7 +2090,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio) | |||
2088 | 2090 | ||
2089 | pd = q->queuedata; | 2091 | pd = q->queuedata; |
2090 | if (!pd) { | 2092 | if (!pd) { |
2091 | printk("pktcdvd: %s incorrect request queue\n", bdevname(bio->bi_bdev, b)); | 2093 | printk(DRIVER_NAME": %s incorrect request queue\n", bdevname(bio->bi_bdev, b)); |
2092 | goto end_io; | 2094 | goto end_io; |
2093 | } | 2095 | } |
2094 | 2096 | ||
@@ -2110,13 +2112,13 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio) | |||
2110 | } | 2112 | } |
2111 | 2113 | ||
2112 | if (!test_bit(PACKET_WRITABLE, &pd->flags)) { | 2114 | if (!test_bit(PACKET_WRITABLE, &pd->flags)) { |
2113 | printk("pktcdvd: WRITE for ro device %s (%llu)\n", | 2115 | printk(DRIVER_NAME": WRITE for ro device %s (%llu)\n", |
2114 | pd->name, (unsigned long long)bio->bi_sector); | 2116 | pd->name, (unsigned long long)bio->bi_sector); |
2115 | goto end_io; | 2117 | goto end_io; |
2116 | } | 2118 | } |
2117 | 2119 | ||
2118 | if (!bio->bi_size || (bio->bi_size % CD_FRAMESIZE)) { | 2120 | if (!bio->bi_size || (bio->bi_size % CD_FRAMESIZE)) { |
2119 | printk("pktcdvd: wrong bio size\n"); | 2121 | printk(DRIVER_NAME": wrong bio size\n"); |
2120 | goto end_io; | 2122 | goto end_io; |
2121 | } | 2123 | } |
2122 | 2124 | ||
@@ -2319,7 +2321,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2319 | struct block_device *bdev; | 2321 | struct block_device *bdev; |
2320 | 2322 | ||
2321 | if (pd->pkt_dev == dev) { | 2323 | if (pd->pkt_dev == dev) { |
2322 | printk("pktcdvd: Recursive setup not allowed\n"); | 2324 | printk(DRIVER_NAME": Recursive setup not allowed\n"); |
2323 | return -EBUSY; | 2325 | return -EBUSY; |
2324 | } | 2326 | } |
2325 | for (i = 0; i < MAX_WRITERS; i++) { | 2327 | for (i = 0; i < MAX_WRITERS; i++) { |
@@ -2327,11 +2329,11 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2327 | if (!pd2) | 2329 | if (!pd2) |
2328 | continue; | 2330 | continue; |
2329 | if (pd2->bdev->bd_dev == dev) { | 2331 | if (pd2->bdev->bd_dev == dev) { |
2330 | printk("pktcdvd: %s already setup\n", bdevname(pd2->bdev, b)); | 2332 | printk(DRIVER_NAME": %s already setup\n", bdevname(pd2->bdev, b)); |
2331 | return -EBUSY; | 2333 | return -EBUSY; |
2332 | } | 2334 | } |
2333 | if (pd2->pkt_dev == dev) { | 2335 | if (pd2->pkt_dev == dev) { |
2334 | printk("pktcdvd: Can't chain pktcdvd devices\n"); | 2336 | printk(DRIVER_NAME": Can't chain pktcdvd devices\n"); |
2335 | return -EBUSY; | 2337 | return -EBUSY; |
2336 | } | 2338 | } |
2337 | } | 2339 | } |
@@ -2354,7 +2356,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2354 | atomic_set(&pd->cdrw.pending_bios, 0); | 2356 | atomic_set(&pd->cdrw.pending_bios, 0); |
2355 | pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->name); | 2357 | pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->name); |
2356 | if (IS_ERR(pd->cdrw.thread)) { | 2358 | if (IS_ERR(pd->cdrw.thread)) { |
2357 | printk("pktcdvd: can't start kernel thread\n"); | 2359 | printk(DRIVER_NAME": can't start kernel thread\n"); |
2358 | ret = -ENOMEM; | 2360 | ret = -ENOMEM; |
2359 | goto out_mem; | 2361 | goto out_mem; |
2360 | } | 2362 | } |
@@ -2364,7 +2366,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2364 | proc->data = pd; | 2366 | proc->data = pd; |
2365 | proc->proc_fops = &pkt_proc_fops; | 2367 | proc->proc_fops = &pkt_proc_fops; |
2366 | } | 2368 | } |
2367 | DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); | 2369 | DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); |
2368 | return 0; | 2370 | return 0; |
2369 | 2371 | ||
2370 | out_mem: | 2372 | out_mem: |
@@ -2401,7 +2403,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2401 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); | 2403 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); |
2402 | 2404 | ||
2403 | default: | 2405 | default: |
2404 | VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); | 2406 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); |
2405 | return -ENOTTY; | 2407 | return -ENOTTY; |
2406 | } | 2408 | } |
2407 | 2409 | ||
@@ -2446,7 +2448,7 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2446 | if (!pkt_devs[idx]) | 2448 | if (!pkt_devs[idx]) |
2447 | break; | 2449 | break; |
2448 | if (idx == MAX_WRITERS) { | 2450 | if (idx == MAX_WRITERS) { |
2449 | printk("pktcdvd: max %d writers supported\n", MAX_WRITERS); | 2451 | printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS); |
2450 | return -EBUSY; | 2452 | return -EBUSY; |
2451 | } | 2453 | } |
2452 | 2454 | ||
@@ -2470,15 +2472,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2470 | 2472 | ||
2471 | spin_lock_init(&pd->lock); | 2473 | spin_lock_init(&pd->lock); |
2472 | spin_lock_init(&pd->iosched.lock); | 2474 | spin_lock_init(&pd->iosched.lock); |
2473 | sprintf(pd->name, "pktcdvd%d", idx); | 2475 | sprintf(pd->name, DRIVER_NAME"%d", idx); |
2474 | init_waitqueue_head(&pd->wqueue); | 2476 | init_waitqueue_head(&pd->wqueue); |
2475 | pd->bio_queue = RB_ROOT; | 2477 | pd->bio_queue = RB_ROOT; |
2476 | 2478 | ||
2477 | disk->major = pkt_major; | 2479 | disk->major = pktdev_major; |
2478 | disk->first_minor = idx; | 2480 | disk->first_minor = idx; |
2479 | disk->fops = &pktcdvd_ops; | 2481 | disk->fops = &pktcdvd_ops; |
2480 | disk->flags = GENHD_FL_REMOVABLE; | 2482 | disk->flags = GENHD_FL_REMOVABLE; |
2481 | sprintf(disk->disk_name, "pktcdvd%d", idx); | 2483 | sprintf(disk->disk_name, DRIVER_NAME"%d", idx); |
2482 | disk->private_data = pd; | 2484 | disk->private_data = pd; |
2483 | disk->queue = blk_alloc_queue(GFP_KERNEL); | 2485 | disk->queue = blk_alloc_queue(GFP_KERNEL); |
2484 | if (!disk->queue) | 2486 | if (!disk->queue) |
@@ -2520,7 +2522,7 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2520 | break; | 2522 | break; |
2521 | } | 2523 | } |
2522 | if (idx == MAX_WRITERS) { | 2524 | if (idx == MAX_WRITERS) { |
2523 | DPRINTK("pktcdvd: dev not setup\n"); | 2525 | DPRINTK(DRIVER_NAME": dev not setup\n"); |
2524 | return -ENXIO; | 2526 | return -ENXIO; |
2525 | } | 2527 | } |
2526 | 2528 | ||
@@ -2533,7 +2535,7 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2533 | blkdev_put(pd->bdev); | 2535 | blkdev_put(pd->bdev); |
2534 | 2536 | ||
2535 | remove_proc_entry(pd->name, pkt_proc); | 2537 | remove_proc_entry(pd->name, pkt_proc); |
2536 | DPRINTK("pktcdvd: writer %s unmapped\n", pd->name); | 2538 | DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name); |
2537 | 2539 | ||
2538 | del_gendisk(pd->disk); | 2540 | del_gendisk(pd->disk); |
2539 | blk_cleanup_queue(pd->disk->queue); | 2541 | blk_cleanup_queue(pd->disk->queue); |
@@ -2610,7 +2612,7 @@ static struct file_operations pkt_ctl_fops = { | |||
2610 | 2612 | ||
2611 | static struct miscdevice pkt_misc = { | 2613 | static struct miscdevice pkt_misc = { |
2612 | .minor = MISC_DYNAMIC_MINOR, | 2614 | .minor = MISC_DYNAMIC_MINOR, |
2613 | .name = "pktcdvd", | 2615 | .name = DRIVER_NAME, |
2614 | .fops = &pkt_ctl_fops | 2616 | .fops = &pkt_ctl_fops |
2615 | }; | 2617 | }; |
2616 | 2618 | ||
@@ -2623,28 +2625,28 @@ static int __init pkt_init(void) | |||
2623 | if (!psd_pool) | 2625 | if (!psd_pool) |
2624 | return -ENOMEM; | 2626 | return -ENOMEM; |
2625 | 2627 | ||
2626 | ret = register_blkdev(pkt_major, "pktcdvd"); | 2628 | ret = register_blkdev(pktdev_major, DRIVER_NAME); |
2627 | if (ret < 0) { | 2629 | if (ret < 0) { |
2628 | printk("pktcdvd: Unable to register block device\n"); | 2630 | printk(DRIVER_NAME": Unable to register block device\n"); |
2629 | goto out2; | 2631 | goto out2; |
2630 | } | 2632 | } |
2631 | if (!pkt_major) | 2633 | if (!pktdev_major) |
2632 | pkt_major = ret; | 2634 | pktdev_major = ret; |
2633 | 2635 | ||
2634 | ret = misc_register(&pkt_misc); | 2636 | ret = misc_register(&pkt_misc); |
2635 | if (ret) { | 2637 | if (ret) { |
2636 | printk("pktcdvd: Unable to register misc device\n"); | 2638 | printk(DRIVER_NAME": Unable to register misc device\n"); |
2637 | goto out; | 2639 | goto out; |
2638 | } | 2640 | } |
2639 | 2641 | ||
2640 | mutex_init(&ctl_mutex); | 2642 | mutex_init(&ctl_mutex); |
2641 | 2643 | ||
2642 | pkt_proc = proc_mkdir("pktcdvd", proc_root_driver); | 2644 | pkt_proc = proc_mkdir(DRIVER_NAME, proc_root_driver); |
2643 | 2645 | ||
2644 | return 0; | 2646 | return 0; |
2645 | 2647 | ||
2646 | out: | 2648 | out: |
2647 | unregister_blkdev(pkt_major, "pktcdvd"); | 2649 | unregister_blkdev(pktdev_major, DRIVER_NAME); |
2648 | out2: | 2650 | out2: |
2649 | mempool_destroy(psd_pool); | 2651 | mempool_destroy(psd_pool); |
2650 | return ret; | 2652 | return ret; |
@@ -2652,9 +2654,9 @@ out2: | |||
2652 | 2654 | ||
2653 | static void __exit pkt_exit(void) | 2655 | static void __exit pkt_exit(void) |
2654 | { | 2656 | { |
2655 | remove_proc_entry("pktcdvd", proc_root_driver); | 2657 | remove_proc_entry(DRIVER_NAME, proc_root_driver); |
2656 | misc_deregister(&pkt_misc); | 2658 | misc_deregister(&pkt_misc); |
2657 | unregister_blkdev(pkt_major, "pktcdvd"); | 2659 | unregister_blkdev(pktdev_major, DRIVER_NAME); |
2658 | mempool_destroy(psd_pool); | 2660 | mempool_destroy(psd_pool); |
2659 | } | 2661 | } |
2660 | 2662 | ||
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index f2305ee792a..fdc8f892eb8 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -636,7 +636,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
636 | intr = in_8(&sw->intr); | 636 | intr = in_8(&sw->intr); |
637 | err = (intr & ERROR_INTR)? in_8(&sw->error): 0; | 637 | err = (intr & ERROR_INTR)? in_8(&sw->error): 0; |
638 | if ((intr & ERROR_INTR) && fs->state != do_transfer) | 638 | if ((intr & ERROR_INTR) && fs->state != do_transfer) |
639 | printk(KERN_ERR "swim3_interrupt, state=%d, dir=%lx, intr=%x, err=%x\n", | 639 | printk(KERN_ERR "swim3_interrupt, state=%d, dir=%x, intr=%x, err=%x\n", |
640 | fs->state, rq_data_dir(fd_req), intr, err); | 640 | fs->state, rq_data_dir(fd_req), intr, err); |
641 | switch (fs->state) { | 641 | switch (fs->state) { |
642 | case locating: | 642 | case locating: |
@@ -742,7 +742,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
742 | if ((stat & ACTIVE) == 0 || resid != 0) { | 742 | if ((stat & ACTIVE) == 0 || resid != 0) { |
743 | /* musta been an error */ | 743 | /* musta been an error */ |
744 | printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); | 744 | printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); |
745 | printk(KERN_ERR " state=%d, dir=%lx, intr=%x, err=%x\n", | 745 | printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n", |
746 | fs->state, rq_data_dir(fd_req), intr, err); | 746 | fs->state, rq_data_dir(fd_req), intr, err); |
747 | end_request(fd_req, 0); | 747 | end_request(fd_req, 0); |
748 | fs->state = idle; | 748 | fs->state = idle; |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 22f8cf218cc..c603bf29158 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config AGP | 1 | config AGP |
2 | tristate "/dev/agpgart (AGP Support)" | 2 | tristate "/dev/agpgart (AGP Support)" |
3 | depends on ALPHA || IA64 || PPC || X86 | 3 | depends on ALPHA || IA64 || PARISC || PPC || X86 |
4 | depends on PCI | 4 | depends on PCI |
5 | ---help--- | 5 | ---help--- |
6 | AGP (Accelerated Graphics Port) is a bus system mainly used to | 6 | AGP (Accelerated Graphics Port) is a bus system mainly used to |
@@ -122,6 +122,14 @@ config AGP_HP_ZX1 | |||
122 | This option gives you AGP GART support for the HP ZX1 chipset | 122 | This option gives you AGP GART support for the HP ZX1 chipset |
123 | for IA64 processors. | 123 | for IA64 processors. |
124 | 124 | ||
125 | config AGP_PARISC | ||
126 | tristate "HP Quicksilver AGP support" | ||
127 | depends on AGP && PARISC && 64BIT | ||
128 | help | ||
129 | This option gives you AGP GART support for the HP Quicksilver | ||
130 | AGP bus adapter on HP PA-RISC machines (Ok, just on the C8000 | ||
131 | workstation...) | ||
132 | |||
125 | config AGP_ALPHA_CORE | 133 | config AGP_ALPHA_CORE |
126 | tristate "Alpha AGP support" | 134 | tristate "Alpha AGP support" |
127 | depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL) | 135 | depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL) |
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile index d33a22f2fa0..3e581603d0a 100644 --- a/drivers/char/agp/Makefile +++ b/drivers/char/agp/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_AGP_AMD64) += amd64-agp.o | |||
8 | obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o | 8 | obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o |
9 | obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o | 9 | obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o |
10 | obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o | 10 | obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o |
11 | obj-$(CONFIG_AGP_PARISC) += parisc-agp.o | ||
11 | obj-$(CONFIG_AGP_I460) += i460-agp.o | 12 | obj-$(CONFIG_AGP_I460) += i460-agp.o |
12 | obj-$(CONFIG_AGP_INTEL) += intel-agp.o | 13 | obj-$(CONFIG_AGP_INTEL) += intel-agp.o |
13 | obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o | 14 | obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o |
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c new file mode 100644 index 00000000000..17c50b0f83f --- /dev/null +++ b/drivers/char/agp/parisc-agp.c | |||
@@ -0,0 +1,416 @@ | |||
1 | /* | ||
2 | * HP Quicksilver AGP GART routines | ||
3 | * | ||
4 | * Copyright (c) 2006, Kyle McMartin <kyle@parisc-linux.org> | ||
5 | * | ||
6 | * Based on drivers/char/agpgart/hp-agp.c which is | ||
7 | * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P. | ||
8 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/klist.h> | ||
20 | #include <linux/agp_backend.h> | ||
21 | |||
22 | #include <asm-parisc/parisc-device.h> | ||
23 | #include <asm-parisc/ropes.h> | ||
24 | |||
25 | #include "agp.h" | ||
26 | |||
27 | #define DRVNAME "quicksilver" | ||
28 | #define DRVPFX DRVNAME ": " | ||
29 | |||
30 | #ifndef log2 | ||
31 | #define log2(x) ffz(~(x)) | ||
32 | #endif | ||
33 | |||
34 | #define AGP8X_MODE_BIT 3 | ||
35 | #define AGP8X_MODE (1 << AGP8X_MODE_BIT) | ||
36 | |||
37 | static struct _parisc_agp_info { | ||
38 | void __iomem *ioc_regs; | ||
39 | void __iomem *lba_regs; | ||
40 | |||
41 | int lba_cap_offset; | ||
42 | |||
43 | u64 *gatt; | ||
44 | u64 gatt_entries; | ||
45 | |||
46 | u64 gart_base; | ||
47 | u64 gart_size; | ||
48 | |||
49 | int io_page_size; | ||
50 | int io_pages_per_kpage; | ||
51 | } parisc_agp_info; | ||
52 | |||
53 | static struct gatt_mask parisc_agp_masks[] = | ||
54 | { | ||
55 | { | ||
56 | .mask = SBA_PDIR_VALID_BIT, | ||
57 | .type = 0 | ||
58 | } | ||
59 | }; | ||
60 | |||
61 | static struct aper_size_info_fixed parisc_agp_sizes[] = | ||
62 | { | ||
63 | {0, 0, 0}, /* filled in by parisc_agp_fetch_size() */ | ||
64 | }; | ||
65 | |||
66 | static int | ||
67 | parisc_agp_fetch_size(void) | ||
68 | { | ||
69 | int size; | ||
70 | |||
71 | size = parisc_agp_info.gart_size / MB(1); | ||
72 | parisc_agp_sizes[0].size = size; | ||
73 | agp_bridge->current_size = (void *) &parisc_agp_sizes[0]; | ||
74 | |||
75 | return size; | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | parisc_agp_configure(void) | ||
80 | { | ||
81 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
82 | |||
83 | agp_bridge->gart_bus_addr = info->gart_base; | ||
84 | agp_bridge->capndx = info->lba_cap_offset; | ||
85 | agp_bridge->mode = readl(info->lba_regs+info->lba_cap_offset+PCI_AGP_STATUS); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static void | ||
91 | parisc_agp_tlbflush(struct agp_memory *mem) | ||
92 | { | ||
93 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
94 | |||
95 | writeq(info->gart_base | log2(info->gart_size), info->ioc_regs+IOC_PCOM); | ||
96 | readq(info->ioc_regs+IOC_PCOM); /* flush */ | ||
97 | } | ||
98 | |||
99 | static int | ||
100 | parisc_agp_create_gatt_table(struct agp_bridge_data *bridge) | ||
101 | { | ||
102 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
103 | int i; | ||
104 | |||
105 | for (i = 0; i < info->gatt_entries; i++) { | ||
106 | info->gatt[i] = (unsigned long)agp_bridge->scratch_page; | ||
107 | } | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int | ||
113 | parisc_agp_free_gatt_table(struct agp_bridge_data *bridge) | ||
114 | { | ||
115 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
116 | |||
117 | info->gatt[0] = SBA_AGPGART_COOKIE; | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int | ||
123 | parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | ||
124 | { | ||
125 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
126 | int i, k; | ||
127 | off_t j, io_pg_start; | ||
128 | int io_pg_count; | ||
129 | |||
130 | if (type != 0 || mem->type != 0) { | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | io_pg_start = info->io_pages_per_kpage * pg_start; | ||
135 | io_pg_count = info->io_pages_per_kpage * mem->page_count; | ||
136 | if ((io_pg_start + io_pg_count) > info->gatt_entries) { | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | j = io_pg_start; | ||
141 | while (j < (io_pg_start + io_pg_count)) { | ||
142 | if (info->gatt[j]) | ||
143 | return -EBUSY; | ||
144 | j++; | ||
145 | } | ||
146 | |||
147 | if (mem->is_flushed == FALSE) { | ||
148 | global_cache_flush(); | ||
149 | mem->is_flushed = TRUE; | ||
150 | } | ||
151 | |||
152 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { | ||
153 | unsigned long paddr; | ||
154 | |||
155 | paddr = mem->memory[i]; | ||
156 | for (k = 0; | ||
157 | k < info->io_pages_per_kpage; | ||
158 | k++, j++, paddr += info->io_page_size) { | ||
159 | info->gatt[j] = | ||
160 | agp_bridge->driver->mask_memory(agp_bridge, | ||
161 | paddr, type); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | agp_bridge->driver->tlb_flush(mem); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int | ||
171 | parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | ||
172 | { | ||
173 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
174 | int i, io_pg_start, io_pg_count; | ||
175 | |||
176 | if (type != 0 || mem->type != 0) { | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | io_pg_start = info->io_pages_per_kpage * pg_start; | ||
181 | io_pg_count = info->io_pages_per_kpage * mem->page_count; | ||
182 | for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) { | ||
183 | info->gatt[i] = agp_bridge->scratch_page; | ||
184 | } | ||
185 | |||
186 | agp_bridge->driver->tlb_flush(mem); | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static unsigned long | ||
191 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, | ||
192 | unsigned long addr, int type) | ||
193 | { | ||
194 | return SBA_PDIR_VALID_BIT | addr; | ||
195 | } | ||
196 | |||
197 | static void | ||
198 | parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode) | ||
199 | { | ||
200 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
201 | u32 command; | ||
202 | |||
203 | command = readl(info->lba_regs + info->lba_cap_offset + PCI_AGP_STATUS); | ||
204 | |||
205 | command = agp_collect_device_status(bridge, mode, command); | ||
206 | command |= 0x00000100; | ||
207 | |||
208 | writel(command, info->lba_regs + info->lba_cap_offset + PCI_AGP_COMMAND); | ||
209 | |||
210 | agp_device_command(command, (mode & AGP8X_MODE) != 0); | ||
211 | } | ||
212 | |||
213 | struct agp_bridge_driver parisc_agp_driver = { | ||
214 | .owner = THIS_MODULE, | ||
215 | .size_type = FIXED_APER_SIZE, | ||
216 | .configure = parisc_agp_configure, | ||
217 | .fetch_size = parisc_agp_fetch_size, | ||
218 | .tlb_flush = parisc_agp_tlbflush, | ||
219 | .mask_memory = parisc_agp_mask_memory, | ||
220 | .masks = parisc_agp_masks, | ||
221 | .agp_enable = parisc_agp_enable, | ||
222 | .cache_flush = global_cache_flush, | ||
223 | .create_gatt_table = parisc_agp_create_gatt_table, | ||
224 | .free_gatt_table = parisc_agp_free_gatt_table, | ||
225 | .insert_memory = parisc_agp_insert_memory, | ||
226 | .remove_memory = parisc_agp_remove_memory, | ||
227 | .alloc_by_type = agp_generic_alloc_by_type, | ||
228 | .free_by_type = agp_generic_free_by_type, | ||
229 | .agp_alloc_page = agp_generic_alloc_page, | ||
230 | .agp_destroy_page = agp_generic_destroy_page, | ||
231 | .cant_use_aperture = 1, | ||
232 | }; | ||
233 | |||
234 | static int __init | ||
235 | agp_ioc_init(void __iomem *ioc_regs) | ||
236 | { | ||
237 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
238 | u64 *iova_base, *io_pdir, io_tlb_ps; | ||
239 | int io_tlb_shift; | ||
240 | |||
241 | printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n"); | ||
242 | |||
243 | info->ioc_regs = ioc_regs; | ||
244 | |||
245 | io_tlb_ps = readq(info->ioc_regs+IOC_TCNFG); | ||
246 | switch (io_tlb_ps) { | ||
247 | case 0: io_tlb_shift = 12; break; | ||
248 | case 1: io_tlb_shift = 13; break; | ||
249 | case 2: io_tlb_shift = 14; break; | ||
250 | case 3: io_tlb_shift = 16; break; | ||
251 | default: | ||
252 | printk(KERN_ERR DRVPFX "Invalid IOTLB page size " | ||
253 | "configuration 0x%llx\n", io_tlb_ps); | ||
254 | info->gatt = NULL; | ||
255 | info->gatt_entries = 0; | ||
256 | return -ENODEV; | ||
257 | } | ||
258 | info->io_page_size = 1 << io_tlb_shift; | ||
259 | info->io_pages_per_kpage = PAGE_SIZE / info->io_page_size; | ||
260 | |||
261 | iova_base = readq(info->ioc_regs+IOC_IBASE) & ~0x1; | ||
262 | info->gart_base = iova_base + PLUTO_IOVA_SIZE - PLUTO_GART_SIZE; | ||
263 | |||
264 | info->gart_size = PLUTO_GART_SIZE; | ||
265 | info->gatt_entries = info->gart_size / info->io_page_size; | ||
266 | |||
267 | io_pdir = phys_to_virt(readq(info->ioc_regs+IOC_PDIR_BASE)); | ||
268 | info->gatt = &io_pdir[(PLUTO_IOVA_SIZE/2) >> PAGE_SHIFT]; | ||
269 | |||
270 | if (info->gatt[0] != SBA_AGPGART_COOKIE) { | ||
271 | info->gatt = NULL; | ||
272 | info->gatt_entries = 0; | ||
273 | printk(KERN_ERR DRVPFX "No reserved IO PDIR entry found; " | ||
274 | "GART disabled\n"); | ||
275 | return -ENODEV; | ||
276 | } | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int | ||
282 | lba_find_capability(int cap) | ||
283 | { | ||
284 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
285 | u16 status; | ||
286 | u8 pos, id; | ||
287 | int ttl = 48; | ||
288 | |||
289 | status = readw(info->lba_regs + PCI_STATUS); | ||
290 | if (!(status & PCI_STATUS_CAP_LIST)) | ||
291 | return 0; | ||
292 | pos = readb(info->lba_regs + PCI_CAPABILITY_LIST); | ||
293 | while (ttl-- && pos >= 0x40) { | ||
294 | pos &= ~3; | ||
295 | id = readb(info->lba_regs + pos + PCI_CAP_LIST_ID); | ||
296 | if (id == 0xff) | ||
297 | break; | ||
298 | if (id == cap) | ||
299 | return pos; | ||
300 | pos = readb(info->lba_regs + pos + PCI_CAP_LIST_NEXT); | ||
301 | } | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static int __init | ||
306 | agp_lba_init(void __iomem *lba_hpa) | ||
307 | { | ||
308 | struct _parisc_agp_info *info = &parisc_agp_info; | ||
309 | int cap; | ||
310 | |||
311 | info->lba_regs = lba_hpa; | ||
312 | info->lba_cap_offset = lba_find_capability(PCI_CAP_ID_AGP); | ||
313 | |||
314 | cap = readl(lba_hpa + info->lba_cap_offset) & 0xff; | ||
315 | if (cap != PCI_CAP_ID_AGP) { | ||
316 | printk(KERN_ERR DRVPFX "Invalid capability ID 0x%02x at 0x%x\n", | ||
317 | cap, info->lba_cap_offset); | ||
318 | return -ENODEV; | ||
319 | } | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int __init | ||
325 | parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) | ||
326 | { | ||
327 | struct pci_dev *fake_bridge_dev = NULL; | ||
328 | struct agp_bridge_data *bridge; | ||
329 | int error = 0; | ||
330 | |||
331 | fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL); | ||
332 | if (!fake_bridge_dev) { | ||
333 | error = -ENOMEM; | ||
334 | goto fail; | ||
335 | } | ||
336 | |||
337 | error = agp_ioc_init(ioc_hpa); | ||
338 | if (error) | ||
339 | goto fail; | ||
340 | |||
341 | error = agp_lba_init(lba_hpa); | ||
342 | if (error) | ||
343 | goto fail; | ||
344 | |||
345 | bridge = agp_alloc_bridge(); | ||
346 | if (!bridge) { | ||
347 | error = -ENOMEM; | ||
348 | goto fail; | ||
349 | } | ||
350 | bridge->driver = &parisc_agp_driver; | ||
351 | |||
352 | fake_bridge_dev->vendor = PCI_VENDOR_ID_HP; | ||
353 | fake_bridge_dev->device = PCI_DEVICE_ID_HP_PCIX_LBA; | ||
354 | bridge->dev = fake_bridge_dev; | ||
355 | |||
356 | error = agp_add_bridge(bridge); | ||
357 | |||
358 | fail: | ||
359 | return error; | ||
360 | } | ||
361 | |||
362 | static struct device *next_device(struct klist_iter *i) { | ||
363 | struct klist_node * n = klist_next(i); | ||
364 | return n ? container_of(n, struct device, knode_parent) : NULL; | ||
365 | } | ||
366 | |||
367 | static int | ||
368 | parisc_agp_init(void) | ||
369 | { | ||
370 | extern struct sba_device *sba_list; | ||
371 | |||
372 | int err = -1; | ||
373 | struct parisc_device *sba = NULL, *lba = NULL; | ||
374 | struct lba_device *lbadev = NULL; | ||
375 | struct device *dev = NULL; | ||
376 | struct klist_iter i; | ||
377 | |||
378 | if (!sba_list) | ||
379 | goto out; | ||
380 | |||
381 | /* Find our parent Pluto */ | ||
382 | sba = sba_list->dev; | ||
383 | if (!IS_PLUTO(sba)) { | ||
384 | printk(KERN_INFO DRVPFX "No Pluto found, so no AGPGART for you.\n"); | ||
385 | goto out; | ||
386 | } | ||
387 | |||
388 | /* Now search our Pluto for our precious AGP device... */ | ||
389 | klist_iter_init(&sba->dev.klist_children, &i); | ||
390 | while ((dev = next_device(&i))) { | ||
391 | struct parisc_device *padev = to_parisc_device(dev); | ||
392 | if (IS_QUICKSILVER(padev)) | ||
393 | lba = padev; | ||
394 | } | ||
395 | klist_iter_exit(&i); | ||
396 | |||
397 | if (!lba) { | ||
398 | printk(KERN_INFO DRVPFX "No AGP devices found.\n"); | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | lbadev = parisc_get_drvdata(lba); | ||
403 | |||
404 | /* w00t, let's go find our cookies... */ | ||
405 | parisc_agp_setup(sba_list->ioc[0].ioc_hpa, lbadev->hba.base_addr); | ||
406 | |||
407 | return 0; | ||
408 | |||
409 | out: | ||
410 | return err; | ||
411 | } | ||
412 | |||
413 | module_init(parisc_agp_init); | ||
414 | |||
415 | MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>"); | ||
416 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index d0e92ed0a36..486f97c3f4e 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -112,17 +112,6 @@ static struct serial_state rs_table[1]; | |||
112 | 112 | ||
113 | #define NR_PORTS ARRAY_SIZE(rs_table) | 113 | #define NR_PORTS ARRAY_SIZE(rs_table) |
114 | 114 | ||
115 | /* | ||
116 | * tmp_buf is used as a temporary buffer by serial_write. We need to | ||
117 | * lock it in case the copy_from_user blocks while swapping in a page, | ||
118 | * and some other program tries to do a serial write at the same time. | ||
119 | * Since the lock will only come under contention when the system is | ||
120 | * swapping and available memory is low, it makes sense to share one | ||
121 | * buffer across all the serial ports, since it significantly saves | ||
122 | * memory if large numbers of serial ports are open. | ||
123 | */ | ||
124 | static unsigned char *tmp_buf; | ||
125 | |||
126 | #include <asm/uaccess.h> | 115 | #include <asm/uaccess.h> |
127 | 116 | ||
128 | #define serial_isroot() (capable(CAP_SYS_ADMIN)) | 117 | #define serial_isroot() (capable(CAP_SYS_ADMIN)) |
@@ -912,7 +901,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count | |||
912 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 901 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
913 | return 0; | 902 | return 0; |
914 | 903 | ||
915 | if (!info->xmit.buf || !tmp_buf) | 904 | if (!info->xmit.buf) |
916 | return 0; | 905 | return 0; |
917 | 906 | ||
918 | local_save_flags(flags); | 907 | local_save_flags(flags); |
@@ -1778,7 +1767,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
1778 | { | 1767 | { |
1779 | struct async_struct *info; | 1768 | struct async_struct *info; |
1780 | int retval, line; | 1769 | int retval, line; |
1781 | unsigned long page; | ||
1782 | 1770 | ||
1783 | line = tty->index; | 1771 | line = tty->index; |
1784 | if ((line < 0) || (line >= NR_PORTS)) { | 1772 | if ((line < 0) || (line >= NR_PORTS)) { |
@@ -1798,17 +1786,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
1798 | #endif | 1786 | #endif |
1799 | info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1787 | info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1800 | 1788 | ||
1801 | if (!tmp_buf) { | ||
1802 | page = get_zeroed_page(GFP_KERNEL); | ||
1803 | if (!page) { | ||
1804 | return -ENOMEM; | ||
1805 | } | ||
1806 | if (tmp_buf) | ||
1807 | free_page(page); | ||
1808 | else | ||
1809 | tmp_buf = (unsigned char *) page; | ||
1810 | } | ||
1811 | |||
1812 | /* | 1789 | /* |
1813 | * If the port is the middle of closing, bail out now | 1790 | * If the port is the middle of closing, bail out now |
1814 | */ | 1791 | */ |
@@ -2090,11 +2067,6 @@ static __exit void rs_exit(void) | |||
2090 | kfree(info); | 2067 | kfree(info); |
2091 | } | 2068 | } |
2092 | 2069 | ||
2093 | if (tmp_buf) { | ||
2094 | free_page((unsigned long) tmp_buf); | ||
2095 | tmp_buf = NULL; | ||
2096 | } | ||
2097 | |||
2098 | release_mem_region(CUSTOM_PHYSADDR+0x30, 4); | 2070 | release_mem_region(CUSTOM_PHYSADDR+0x30, 4); |
2099 | } | 2071 | } |
2100 | 2072 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index f85b4eb1661..87b2fb51087 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -748,18 +748,6 @@ static struct cyclades_port cy_port[NR_PORTS]; | |||
748 | static int cy_next_channel; /* next minor available */ | 748 | static int cy_next_channel; /* next minor available */ |
749 | 749 | ||
750 | /* | 750 | /* |
751 | * tmp_buf is used as a temporary buffer by serial_write. We need to | ||
752 | * lock it in case the copy_from_user blocks while swapping in a page, | ||
753 | * and some other program tries to do a serial write at the same time. | ||
754 | * Since the lock will only come under contention when the system is | ||
755 | * swapping and available memory is low, it makes sense to share one | ||
756 | * buffer across all the serial ports, since it significantly saves | ||
757 | * memory if large numbers of serial ports are open. This buffer is | ||
758 | * allocated when the first cy_open occurs. | ||
759 | */ | ||
760 | static unsigned char *tmp_buf; | ||
761 | |||
762 | /* | ||
763 | * This is used to look up the divisor speeds and the timeouts | 751 | * This is used to look up the divisor speeds and the timeouts |
764 | * We're normally limited to 15 distinct baud rates. The extra | 752 | * We're normally limited to 15 distinct baud rates. The extra |
765 | * are accessed via settings in info->flags. | 753 | * are accessed via settings in info->flags. |
@@ -2466,7 +2454,6 @@ cy_open(struct tty_struct *tty, struct file * filp) | |||
2466 | { | 2454 | { |
2467 | struct cyclades_port *info; | 2455 | struct cyclades_port *info; |
2468 | int retval, line; | 2456 | int retval, line; |
2469 | unsigned long page; | ||
2470 | 2457 | ||
2471 | line = tty->index; | 2458 | line = tty->index; |
2472 | if ((line < 0) || (NR_PORTS <= line)){ | 2459 | if ((line < 0) || (NR_PORTS <= line)){ |
@@ -2545,15 +2532,6 @@ cy_open(struct tty_struct *tty, struct file * filp) | |||
2545 | printk("cyc:cy_open (%d): incrementing count to %d\n", | 2532 | printk("cyc:cy_open (%d): incrementing count to %d\n", |
2546 | current->pid, info->count); | 2533 | current->pid, info->count); |
2547 | #endif | 2534 | #endif |
2548 | if (!tmp_buf) { | ||
2549 | page = get_zeroed_page(GFP_KERNEL); | ||
2550 | if (!page) | ||
2551 | return -ENOMEM; | ||
2552 | if (tmp_buf) | ||
2553 | free_page(page); | ||
2554 | else | ||
2555 | tmp_buf = (unsigned char *) page; | ||
2556 | } | ||
2557 | 2535 | ||
2558 | /* | 2536 | /* |
2559 | * If the port is the middle of closing, bail out now | 2537 | * If the port is the middle of closing, bail out now |
@@ -2832,7 +2810,7 @@ cy_write(struct tty_struct * tty, const unsigned char *buf, int count) | |||
2832 | return 0; | 2810 | return 0; |
2833 | } | 2811 | } |
2834 | 2812 | ||
2835 | if (!info->xmit_buf || !tmp_buf) | 2813 | if (!info->xmit_buf) |
2836 | return 0; | 2814 | return 0; |
2837 | 2815 | ||
2838 | CY_LOCK(info, flags); | 2816 | CY_LOCK(info, flags); |
@@ -5490,10 +5468,6 @@ cy_cleanup_module(void) | |||
5490 | #endif | 5468 | #endif |
5491 | } | 5469 | } |
5492 | } | 5470 | } |
5493 | if (tmp_buf) { | ||
5494 | free_page((unsigned long) tmp_buf); | ||
5495 | tmp_buf = NULL; | ||
5496 | } | ||
5497 | } /* cy_cleanup_module */ | 5471 | } /* cy_cleanup_module */ |
5498 | 5472 | ||
5499 | module_init(cy_init); | 5473 | module_init(cy_init); |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 3baa2ab8cbd..c3f95583a12 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -1113,11 +1113,8 @@ static void __exit epca_module_exit(void) | |||
1113 | ch = card_ptr[crd]; | 1113 | ch = card_ptr[crd]; |
1114 | for (count = 0; count < bd->numports; count++, ch++) | 1114 | for (count = 0; count < bd->numports; count++, ch++) |
1115 | { /* Begin for each port */ | 1115 | { /* Begin for each port */ |
1116 | if (ch) { | 1116 | if (ch && ch->tty) |
1117 | if (ch->tty) | 1117 | tty_hangup(ch->tty); |
1118 | tty_hangup(ch->tty); | ||
1119 | kfree(ch->tmp_buf); | ||
1120 | } | ||
1121 | } /* End for each port */ | 1118 | } /* End for each port */ |
1122 | } /* End for each card */ | 1119 | } /* End for each card */ |
1123 | pci_unregister_driver (&epca_driver); | 1120 | pci_unregister_driver (&epca_driver); |
@@ -1635,16 +1632,6 @@ static void post_fep_init(unsigned int crd) | |||
1635 | init_waitqueue_head(&ch->close_wait); | 1632 | init_waitqueue_head(&ch->close_wait); |
1636 | 1633 | ||
1637 | spin_unlock_irqrestore(&epca_lock, flags); | 1634 | spin_unlock_irqrestore(&epca_lock, flags); |
1638 | |||
1639 | ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL); | ||
1640 | if (!ch->tmp_buf) { | ||
1641 | printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i); | ||
1642 | release_region((int)bd->port, 4); | ||
1643 | while(i-- > 0) | ||
1644 | kfree((ch--)->tmp_buf); | ||
1645 | return; | ||
1646 | } else | ||
1647 | memset((void *)ch->tmp_buf,0,ch->txbufsize); | ||
1648 | } /* End for each port */ | 1635 | } /* End for each port */ |
1649 | 1636 | ||
1650 | printk(KERN_INFO | 1637 | printk(KERN_INFO |
diff --git a/drivers/char/epca.h b/drivers/char/epca.h index 456d6c8f94a..a297238cd3b 100644 --- a/drivers/char/epca.h +++ b/drivers/char/epca.h | |||
@@ -130,7 +130,6 @@ struct channel | |||
130 | unsigned long c_oflag; | 130 | unsigned long c_oflag; |
131 | unsigned char __iomem *txptr; | 131 | unsigned char __iomem *txptr; |
132 | unsigned char __iomem *rxptr; | 132 | unsigned char __iomem *rxptr; |
133 | unsigned char *tmp_buf; | ||
134 | struct board_info *board; | 133 | struct board_info *board; |
135 | struct board_chan __iomem *brdchan; | 134 | struct board_chan __iomem *brdchan; |
136 | struct digi_struct digiext; | 135 | struct digi_struct digiext; |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 4711d9b3a59..87127e49c0d 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -33,8 +33,6 @@ | |||
33 | 33 | ||
34 | #define DEBUG | 34 | #define DEBUG |
35 | 35 | ||
36 | static char * tmp_buf; | ||
37 | |||
38 | static int gs_debug; | 36 | static int gs_debug; |
39 | 37 | ||
40 | #ifdef DEBUG | 38 | #ifdef DEBUG |
@@ -205,7 +203,7 @@ int gs_write(struct tty_struct * tty, | |||
205 | if (!tty) return -EIO; | 203 | if (!tty) return -EIO; |
206 | 204 | ||
207 | port = tty->driver_data; | 205 | port = tty->driver_data; |
208 | if (!port || !port->xmit_buf || !tmp_buf) | 206 | if (!port || !port->xmit_buf) |
209 | return -EIO; | 207 | return -EIO; |
210 | 208 | ||
211 | local_save_flags(flags); | 209 | local_save_flags(flags); |
@@ -837,24 +835,9 @@ void gs_set_termios (struct tty_struct * tty, | |||
837 | int gs_init_port(struct gs_port *port) | 835 | int gs_init_port(struct gs_port *port) |
838 | { | 836 | { |
839 | unsigned long flags; | 837 | unsigned long flags; |
840 | unsigned long page; | ||
841 | 838 | ||
842 | func_enter (); | 839 | func_enter (); |
843 | 840 | ||
844 | if (!tmp_buf) { | ||
845 | page = get_zeroed_page(GFP_KERNEL); | ||
846 | spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */ | ||
847 | if (tmp_buf) | ||
848 | free_page(page); | ||
849 | else | ||
850 | tmp_buf = (unsigned char *) page; | ||
851 | spin_unlock_irqrestore (&port->driver_lock, flags); | ||
852 | if (!tmp_buf) { | ||
853 | func_exit (); | ||
854 | return -ENOMEM; | ||
855 | } | ||
856 | } | ||
857 | |||
858 | if (port->flags & ASYNC_INITIALIZED) { | 841 | if (port->flags & ASYNC_INITIALIZED) { |
859 | func_exit (); | 842 | func_exit (); |
860 | return 0; | 843 | return 0; |
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index 8b6f197e5f8..f144a947bd1 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/hvconsole.h> | 29 | #include <asm/hvconsole.h> |
30 | #include <asm/vio.h> | 30 | #include <asm/vio.h> |
31 | #include <asm/prom.h> | 31 | #include <asm/prom.h> |
32 | #include <asm/firmware.h> | ||
32 | #include <asm/iseries/vio.h> | 33 | #include <asm/iseries/vio.h> |
33 | #include <asm/iseries/hv_call.h> | 34 | #include <asm/iseries/hv_call.h> |
34 | #include <asm/iseries/hv_lp_config.h> | 35 | #include <asm/iseries/hv_lp_config.h> |
@@ -488,6 +489,9 @@ static int hvc_vio_init(void) | |||
488 | atomic_t wait_flag; | 489 | atomic_t wait_flag; |
489 | int rc; | 490 | int rc; |
490 | 491 | ||
492 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
493 | return -EIO; | ||
494 | |||
491 | /* +2 for fudge */ | 495 | /* +2 for fudge */ |
492 | rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), | 496 | rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), |
493 | viomajorsubtype_chario, VIOCHAR_WINDOW + 2); | 497 | viomajorsubtype_chario, VIOCHAR_WINDOW + 2); |
@@ -562,7 +566,7 @@ static int hvc_find_vtys(void) | |||
562 | 566 | ||
563 | for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL; | 567 | for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL; |
564 | vty = of_find_node_by_name(vty, "vty")) { | 568 | vty = of_find_node_by_name(vty, "vty")) { |
565 | uint32_t *vtermno; | 569 | const uint32_t *vtermno; |
566 | 570 | ||
567 | /* We have statically defined space for only a certain number | 571 | /* We have statically defined space for only a certain number |
568 | * of console adapters. | 572 | * of console adapters. |
@@ -571,7 +575,7 @@ static int hvc_find_vtys(void) | |||
571 | (num_found >= VTTY_PORTS)) | 575 | (num_found >= VTTY_PORTS)) |
572 | break; | 576 | break; |
573 | 577 | ||
574 | vtermno = (uint32_t *)get_property(vty, "reg", NULL); | 578 | vtermno = get_property(vty, "reg", NULL); |
575 | if (!vtermno) | 579 | if (!vtermno) |
576 | continue; | 580 | continue; |
577 | 581 | ||
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index cc95941148f..f9c00844d2b 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/hvconsole.h> | 35 | #include <asm/hvconsole.h> |
36 | #include <asm/vio.h> | 36 | #include <asm/vio.h> |
37 | #include <asm/prom.h> | 37 | #include <asm/prom.h> |
38 | #include <asm/firmware.h> | ||
38 | 39 | ||
39 | #include "hvc_console.h" | 40 | #include "hvc_console.h" |
40 | 41 | ||
@@ -120,6 +121,9 @@ static int hvc_vio_init(void) | |||
120 | { | 121 | { |
121 | int rc; | 122 | int rc; |
122 | 123 | ||
124 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
125 | return -EIO; | ||
126 | |||
123 | /* Register as a vio device to receive callbacks */ | 127 | /* Register as a vio device to receive callbacks */ |
124 | rc = vio_register_driver(&hvc_vio_driver); | 128 | rc = vio_register_driver(&hvc_vio_driver); |
125 | 129 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 214d850112f..b0ab3f28cc6 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -81,7 +81,6 @@ | |||
81 | 81 | ||
82 | static struct riscom_board * IRQ_to_board[16]; | 82 | static struct riscom_board * IRQ_to_board[16]; |
83 | static struct tty_driver *riscom_driver; | 83 | static struct tty_driver *riscom_driver; |
84 | static unsigned char * tmp_buf; | ||
85 | 84 | ||
86 | static unsigned long baud_table[] = { | 85 | static unsigned long baud_table[] = { |
87 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | 86 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, |
@@ -1124,7 +1123,7 @@ static int rc_write(struct tty_struct * tty, | |||
1124 | 1123 | ||
1125 | bp = port_Board(port); | 1124 | bp = port_Board(port); |
1126 | 1125 | ||
1127 | if (!tty || !port->xmit_buf || !tmp_buf) | 1126 | if (!tty || !port->xmit_buf) |
1128 | return 0; | 1127 | return 0; |
1129 | 1128 | ||
1130 | save_flags(flags); | 1129 | save_flags(flags); |
@@ -1612,11 +1611,6 @@ static inline int rc_init_drivers(void) | |||
1612 | if (!riscom_driver) | 1611 | if (!riscom_driver) |
1613 | return -ENOMEM; | 1612 | return -ENOMEM; |
1614 | 1613 | ||
1615 | if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) { | ||
1616 | printk(KERN_ERR "rc: Couldn't get free page.\n"); | ||
1617 | put_tty_driver(riscom_driver); | ||
1618 | return 1; | ||
1619 | } | ||
1620 | memset(IRQ_to_board, 0, sizeof(IRQ_to_board)); | 1614 | memset(IRQ_to_board, 0, sizeof(IRQ_to_board)); |
1621 | riscom_driver->owner = THIS_MODULE; | 1615 | riscom_driver->owner = THIS_MODULE; |
1622 | riscom_driver->name = "ttyL"; | 1616 | riscom_driver->name = "ttyL"; |
@@ -1629,7 +1623,6 @@ static inline int rc_init_drivers(void) | |||
1629 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; | 1623 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; |
1630 | tty_set_operations(riscom_driver, &riscom_ops); | 1624 | tty_set_operations(riscom_driver, &riscom_ops); |
1631 | if ((error = tty_register_driver(riscom_driver))) { | 1625 | if ((error = tty_register_driver(riscom_driver))) { |
1632 | free_page((unsigned long)tmp_buf); | ||
1633 | put_tty_driver(riscom_driver); | 1626 | put_tty_driver(riscom_driver); |
1634 | printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " | 1627 | printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " |
1635 | "error = %d\n", | 1628 | "error = %d\n", |
@@ -1657,7 +1650,6 @@ static void rc_release_drivers(void) | |||
1657 | 1650 | ||
1658 | save_flags(flags); | 1651 | save_flags(flags); |
1659 | cli(); | 1652 | cli(); |
1660 | free_page((unsigned long)tmp_buf); | ||
1661 | tty_unregister_driver(riscom_driver); | 1653 | tty_unregister_driver(riscom_driver); |
1662 | put_tty_driver(riscom_driver); | 1654 | put_tty_driver(riscom_driver); |
1663 | restore_flags(flags); | 1655 | restore_flags(flags); |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index b4ea1266b66..f4809c8183c 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -119,17 +119,6 @@ struct cyclades_port cy_port[] = { | |||
119 | #define NR_PORTS ARRAY_SIZE(cy_port) | 119 | #define NR_PORTS ARRAY_SIZE(cy_port) |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * tmp_buf is used as a temporary buffer by serial_write. We need to | ||
123 | * lock it in case the copy_from_user blocks while swapping in a page, | ||
124 | * and some other program tries to do a serial write at the same time. | ||
125 | * Since the lock will only come under contention when the system is | ||
126 | * swapping and available memory is low, it makes sense to share one | ||
127 | * buffer across all the serial ports, since it significantly saves | ||
128 | * memory if large numbers of serial ports are open. | ||
129 | */ | ||
130 | static unsigned char *tmp_buf = 0; | ||
131 | |||
132 | /* | ||
133 | * This is used to look up the divisor speeds and the timeouts | 122 | * This is used to look up the divisor speeds and the timeouts |
134 | * We're normally limited to 15 distinct baud rates. The extra | 123 | * We're normally limited to 15 distinct baud rates. The extra |
135 | * are accessed via settings in info->flags. | 124 | * are accessed via settings in info->flags. |
@@ -1132,7 +1121,7 @@ cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
1132 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) | 1121 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) |
1133 | return; | 1122 | return; |
1134 | 1123 | ||
1135 | if (!tty || !info->xmit_buf) | 1124 | if (!info->xmit_buf) |
1136 | return; | 1125 | return; |
1137 | 1126 | ||
1138 | local_irq_save(flags); | 1127 | local_irq_save(flags); |
@@ -1198,7 +1187,7 @@ cy_write(struct tty_struct * tty, | |||
1198 | return 0; | 1187 | return 0; |
1199 | } | 1188 | } |
1200 | 1189 | ||
1201 | if (!tty || !info->xmit_buf || !tmp_buf){ | 1190 | if (!info->xmit_buf){ |
1202 | return 0; | 1191 | return 0; |
1203 | } | 1192 | } |
1204 | 1193 | ||
@@ -1983,13 +1972,6 @@ cy_open(struct tty_struct *tty, struct file * filp) | |||
1983 | tty->driver_data = info; | 1972 | tty->driver_data = info; |
1984 | info->tty = tty; | 1973 | info->tty = tty; |
1985 | 1974 | ||
1986 | if (!tmp_buf) { | ||
1987 | tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL); | ||
1988 | if (!tmp_buf){ | ||
1989 | return -ENOMEM; | ||
1990 | } | ||
1991 | } | ||
1992 | |||
1993 | /* | 1975 | /* |
1994 | * Start up serial port | 1976 | * Start up serial port |
1995 | */ | 1977 | */ |
diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c index d418b829721..22915cc46ba 100644 --- a/drivers/clocksource/scx200_hrt.c +++ b/drivers/clocksource/scx200_hrt.c | |||
@@ -63,7 +63,7 @@ static struct clocksource cs_hrt = { | |||
63 | 63 | ||
64 | static int __init init_hrt_clocksource(void) | 64 | static int __init init_hrt_clocksource(void) |
65 | { | 65 | { |
66 | /* Make sure scx200 has initializedd the configuration block */ | 66 | /* Make sure scx200 has initialized the configuration block */ |
67 | if (!scx200_cb_present()) | 67 | if (!scx200_cb_present()) |
68 | return -ENODEV; | 68 | return -ENODEV; |
69 | 69 | ||
@@ -76,7 +76,7 @@ static int __init init_hrt_clocksource(void) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /* write timer config */ | 78 | /* write timer config */ |
79 | outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0, | 79 | outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0), |
80 | scx200_cb_base + SCx200_TMCNFG_OFFSET); | 80 | scx200_cb_base + SCx200_TMCNFG_OFFSET); |
81 | 81 | ||
82 | if (mhz27) { | 82 | if (mhz27) { |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2caaf71d80c..86e69b7f912 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -52,8 +52,14 @@ static void handle_update(void *data); | |||
52 | * The mutex locks both lists. | 52 | * The mutex locks both lists. |
53 | */ | 53 | */ |
54 | static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); | 54 | static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); |
55 | static BLOCKING_NOTIFIER_HEAD(cpufreq_transition_notifier_list); | 55 | static struct srcu_notifier_head cpufreq_transition_notifier_list; |
56 | 56 | ||
57 | static int __init init_cpufreq_transition_notifier_list(void) | ||
58 | { | ||
59 | srcu_init_notifier_head(&cpufreq_transition_notifier_list); | ||
60 | return 0; | ||
61 | } | ||
62 | core_initcall(init_cpufreq_transition_notifier_list); | ||
57 | 63 | ||
58 | static LIST_HEAD(cpufreq_governor_list); | 64 | static LIST_HEAD(cpufreq_governor_list); |
59 | static DEFINE_MUTEX (cpufreq_governor_mutex); | 65 | static DEFINE_MUTEX (cpufreq_governor_mutex); |
@@ -262,14 +268,14 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | |||
262 | freqs->old = policy->cur; | 268 | freqs->old = policy->cur; |
263 | } | 269 | } |
264 | } | 270 | } |
265 | blocking_notifier_call_chain(&cpufreq_transition_notifier_list, | 271 | srcu_notifier_call_chain(&cpufreq_transition_notifier_list, |
266 | CPUFREQ_PRECHANGE, freqs); | 272 | CPUFREQ_PRECHANGE, freqs); |
267 | adjust_jiffies(CPUFREQ_PRECHANGE, freqs); | 273 | adjust_jiffies(CPUFREQ_PRECHANGE, freqs); |
268 | break; | 274 | break; |
269 | 275 | ||
270 | case CPUFREQ_POSTCHANGE: | 276 | case CPUFREQ_POSTCHANGE: |
271 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); | 277 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); |
272 | blocking_notifier_call_chain(&cpufreq_transition_notifier_list, | 278 | srcu_notifier_call_chain(&cpufreq_transition_notifier_list, |
273 | CPUFREQ_POSTCHANGE, freqs); | 279 | CPUFREQ_POSTCHANGE, freqs); |
274 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) | 280 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) |
275 | policy->cur = freqs->new; | 281 | policy->cur = freqs->new; |
@@ -1049,7 +1055,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) | |||
1049 | freqs.old = cpu_policy->cur; | 1055 | freqs.old = cpu_policy->cur; |
1050 | freqs.new = cur_freq; | 1056 | freqs.new = cur_freq; |
1051 | 1057 | ||
1052 | blocking_notifier_call_chain(&cpufreq_transition_notifier_list, | 1058 | srcu_notifier_call_chain(&cpufreq_transition_notifier_list, |
1053 | CPUFREQ_SUSPENDCHANGE, &freqs); | 1059 | CPUFREQ_SUSPENDCHANGE, &freqs); |
1054 | adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); | 1060 | adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); |
1055 | 1061 | ||
@@ -1130,7 +1136,7 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
1130 | freqs.old = cpu_policy->cur; | 1136 | freqs.old = cpu_policy->cur; |
1131 | freqs.new = cur_freq; | 1137 | freqs.new = cur_freq; |
1132 | 1138 | ||
1133 | blocking_notifier_call_chain( | 1139 | srcu_notifier_call_chain( |
1134 | &cpufreq_transition_notifier_list, | 1140 | &cpufreq_transition_notifier_list, |
1135 | CPUFREQ_RESUMECHANGE, &freqs); | 1141 | CPUFREQ_RESUMECHANGE, &freqs); |
1136 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); | 1142 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); |
@@ -1176,7 +1182,7 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) | |||
1176 | 1182 | ||
1177 | switch (list) { | 1183 | switch (list) { |
1178 | case CPUFREQ_TRANSITION_NOTIFIER: | 1184 | case CPUFREQ_TRANSITION_NOTIFIER: |
1179 | ret = blocking_notifier_chain_register( | 1185 | ret = srcu_notifier_chain_register( |
1180 | &cpufreq_transition_notifier_list, nb); | 1186 | &cpufreq_transition_notifier_list, nb); |
1181 | break; | 1187 | break; |
1182 | case CPUFREQ_POLICY_NOTIFIER: | 1188 | case CPUFREQ_POLICY_NOTIFIER: |
@@ -1208,7 +1214,7 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) | |||
1208 | 1214 | ||
1209 | switch (list) { | 1215 | switch (list) { |
1210 | case CPUFREQ_TRANSITION_NOTIFIER: | 1216 | case CPUFREQ_TRANSITION_NOTIFIER: |
1211 | ret = blocking_notifier_chain_unregister( | 1217 | ret = srcu_notifier_chain_unregister( |
1212 | &cpufreq_transition_notifier_list, nb); | 1218 | &cpufreq_transition_notifier_list, nb); |
1213 | break; | 1219 | break; |
1214 | case CPUFREQ_POLICY_NOTIFIER: | 1220 | case CPUFREQ_POLICY_NOTIFIER: |
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index 489022bdef7..0945336c28d 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c | |||
@@ -13,7 +13,6 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | |||
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include "hisax.h" | 17 | #include "hisax.h" |
19 | #include "isac.h" | 18 | #include "isac.h" |
@@ -45,33 +44,31 @@ static const char *niccy_revision = "$Revision: 1.21.2.4 $"; | |||
45 | #define PCI_IRQ_DISABLE 0xff0000 | 44 | #define PCI_IRQ_DISABLE 0xff0000 |
46 | #define PCI_IRQ_ASSERT 0x800000 | 45 | #define PCI_IRQ_ASSERT 0x800000 |
47 | 46 | ||
48 | static inline u_char | 47 | static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) |
49 | readreg(unsigned int ale, unsigned int adr, u_char off) | ||
50 | { | 48 | { |
51 | register u_char ret; | 49 | register u_char ret; |
52 | 50 | ||
53 | byteout(ale, off); | 51 | byteout(ale, off); |
54 | ret = bytein(adr); | 52 | ret = bytein(adr); |
55 | return (ret); | 53 | return ret; |
56 | } | 54 | } |
57 | 55 | ||
58 | static inline void | 56 | static inline void readfifo(unsigned int ale, unsigned int adr, u_char off, |
59 | readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) | 57 | u_char *data, int size) |
60 | { | 58 | { |
61 | byteout(ale, off); | 59 | byteout(ale, off); |
62 | insb(adr, data, size); | 60 | insb(adr, data, size); |
63 | } | 61 | } |
64 | 62 | ||
65 | 63 | static inline void writereg(unsigned int ale, unsigned int adr, u_char off, | |
66 | static inline void | 64 | u_char data) |
67 | writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) | ||
68 | { | 65 | { |
69 | byteout(ale, off); | 66 | byteout(ale, off); |
70 | byteout(adr, data); | 67 | byteout(adr, data); |
71 | } | 68 | } |
72 | 69 | ||
73 | static inline void | 70 | static inline void writefifo(unsigned int ale, unsigned int adr, u_char off, |
74 | writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) | 71 | u_char *data, int size) |
75 | { | 72 | { |
76 | byteout(ale, off); | 73 | byteout(ale, off); |
77 | outsb(adr, data, size); | 74 | outsb(adr, data, size); |
@@ -79,39 +76,34 @@ writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int siz | |||
79 | 76 | ||
80 | /* Interface functions */ | 77 | /* Interface functions */ |
81 | 78 | ||
82 | static u_char | 79 | static u_char ReadISAC(struct IsdnCardState *cs, u_char offset) |
83 | ReadISAC(struct IsdnCardState *cs, u_char offset) | ||
84 | { | 80 | { |
85 | return (readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset)); | 81 | return readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset); |
86 | } | 82 | } |
87 | 83 | ||
88 | static void | 84 | static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) |
89 | WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) | ||
90 | { | 85 | { |
91 | writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value); | 86 | writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value); |
92 | } | 87 | } |
93 | 88 | ||
94 | static void | 89 | static void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) |
95 | ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) | ||
96 | { | 90 | { |
97 | readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size); | 91 | readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size); |
98 | } | 92 | } |
99 | 93 | ||
100 | static void | 94 | static void WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) |
101 | WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) | ||
102 | { | 95 | { |
103 | writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size); | 96 | writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size); |
104 | } | 97 | } |
105 | 98 | ||
106 | static u_char | 99 | static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) |
107 | ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) | ||
108 | { | 100 | { |
109 | return (readreg(cs->hw.niccy.hscx_ale, | 101 | return readreg(cs->hw.niccy.hscx_ale, |
110 | cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0))); | 102 | cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0)); |
111 | } | 103 | } |
112 | 104 | ||
113 | static void | 105 | static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, |
114 | WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) | 106 | u_char value) |
115 | { | 107 | { |
116 | writereg(cs->hw.niccy.hscx_ale, | 108 | writereg(cs->hw.niccy.hscx_ale, |
117 | cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value); | 109 | cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value); |
@@ -130,8 +122,8 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) | |||
130 | 122 | ||
131 | #include "hscx_irq.c" | 123 | #include "hscx_irq.c" |
132 | 124 | ||
133 | static irqreturn_t | 125 | static irqreturn_t niccy_interrupt(int intno, void *dev_id, |
134 | niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs) | 126 | struct pt_regs *regs) |
135 | { | 127 | { |
136 | struct IsdnCardState *cs = dev_id; | 128 | struct IsdnCardState *cs = dev_id; |
137 | u_char val; | 129 | u_char val; |
@@ -141,21 +133,23 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
141 | if (cs->subtyp == NICCY_PCI) { | 133 | if (cs->subtyp == NICCY_PCI) { |
142 | int ival; | 134 | int ival; |
143 | ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); | 135 | ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); |
144 | if (!(ival & PCI_IRQ_ASSERT)) { /* IRQ not for us (shared) */ | 136 | if (!(ival & PCI_IRQ_ASSERT)) { /* IRQ not for us (shared) */ |
145 | spin_unlock_irqrestore(&cs->lock, flags); | 137 | spin_unlock_irqrestore(&cs->lock, flags); |
146 | return IRQ_NONE; | 138 | return IRQ_NONE; |
147 | } | 139 | } |
148 | outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); | 140 | outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); |
149 | } | 141 | } |
150 | val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40); | 142 | val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, |
151 | Start_HSCX: | 143 | HSCX_ISTA + 0x40); |
144 | Start_HSCX: | ||
152 | if (val) | 145 | if (val) |
153 | hscx_int_main(cs, val); | 146 | hscx_int_main(cs, val); |
154 | val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA); | 147 | val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA); |
155 | Start_ISAC: | 148 | Start_ISAC: |
156 | if (val) | 149 | if (val) |
157 | isac_interrupt(cs, val); | 150 | isac_interrupt(cs, val); |
158 | val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40); | 151 | val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, |
152 | HSCX_ISTA + 0x40); | ||
159 | if (val) { | 153 | if (val) { |
160 | if (cs->debug & L1_DEB_HSCX) | 154 | if (cs->debug & L1_DEB_HSCX) |
161 | debugl1(cs, "HSCX IntStat after IntRoutine"); | 155 | debugl1(cs, "HSCX IntStat after IntRoutine"); |
@@ -168,21 +162,21 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
168 | goto Start_ISAC; | 162 | goto Start_ISAC; |
169 | } | 163 | } |
170 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF); | 164 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF); |
171 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0xFF); | 165 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, |
166 | 0xFF); | ||
172 | writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF); | 167 | writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF); |
173 | writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0); | 168 | writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0); |
174 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0); | 169 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0); |
175 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0); | 170 | writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40,0); |
176 | spin_unlock_irqrestore(&cs->lock, flags); | 171 | spin_unlock_irqrestore(&cs->lock, flags); |
177 | return IRQ_HANDLED; | 172 | return IRQ_HANDLED; |
178 | } | 173 | } |
179 | 174 | ||
180 | static void | 175 | static void release_io_niccy(struct IsdnCardState *cs) |
181 | release_io_niccy(struct IsdnCardState *cs) | ||
182 | { | 176 | { |
183 | if (cs->subtyp == NICCY_PCI) { | 177 | if (cs->subtyp == NICCY_PCI) { |
184 | int val; | 178 | int val; |
185 | 179 | ||
186 | val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); | 180 | val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); |
187 | val &= PCI_IRQ_DISABLE; | 181 | val &= PCI_IRQ_DISABLE; |
188 | outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); | 182 | outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); |
@@ -194,8 +188,7 @@ release_io_niccy(struct IsdnCardState *cs) | |||
194 | } | 188 | } |
195 | } | 189 | } |
196 | 190 | ||
197 | static void | 191 | static void niccy_reset(struct IsdnCardState *cs) |
198 | niccy_reset(struct IsdnCardState *cs) | ||
199 | { | 192 | { |
200 | if (cs->subtyp == NICCY_PCI) { | 193 | if (cs->subtyp == NICCY_PCI) { |
201 | int val; | 194 | int val; |
@@ -207,29 +200,28 @@ niccy_reset(struct IsdnCardState *cs) | |||
207 | inithscxisac(cs, 3); | 200 | inithscxisac(cs, 3); |
208 | } | 201 | } |
209 | 202 | ||
210 | static int | 203 | static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg) |
211 | niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg) | ||
212 | { | 204 | { |
213 | u_long flags; | 205 | u_long flags; |
214 | 206 | ||
215 | switch (mt) { | 207 | switch (mt) { |
216 | case CARD_RESET: | 208 | case CARD_RESET: |
217 | spin_lock_irqsave(&cs->lock, flags); | 209 | spin_lock_irqsave(&cs->lock, flags); |
218 | niccy_reset(cs); | 210 | niccy_reset(cs); |
219 | spin_unlock_irqrestore(&cs->lock, flags); | 211 | spin_unlock_irqrestore(&cs->lock, flags); |
220 | return(0); | 212 | return 0; |
221 | case CARD_RELEASE: | 213 | case CARD_RELEASE: |
222 | release_io_niccy(cs); | 214 | release_io_niccy(cs); |
223 | return(0); | 215 | return 0; |
224 | case CARD_INIT: | 216 | case CARD_INIT: |
225 | spin_lock_irqsave(&cs->lock, flags); | 217 | spin_lock_irqsave(&cs->lock, flags); |
226 | niccy_reset(cs); | 218 | niccy_reset(cs); |
227 | spin_unlock_irqrestore(&cs->lock, flags); | 219 | spin_unlock_irqrestore(&cs->lock, flags); |
228 | return(0); | 220 | return 0; |
229 | case CARD_TEST: | 221 | case CARD_TEST: |
230 | return(0); | 222 | return 0; |
231 | } | 223 | } |
232 | return(0); | 224 | return 0; |
233 | } | 225 | } |
234 | 226 | ||
235 | static struct pci_dev *niccy_dev __devinitdata = NULL; | 227 | static struct pci_dev *niccy_dev __devinitdata = NULL; |
@@ -237,8 +229,7 @@ static struct pci_dev *niccy_dev __devinitdata = NULL; | |||
237 | static struct pnp_card *pnp_c __devinitdata = NULL; | 229 | static struct pnp_card *pnp_c __devinitdata = NULL; |
238 | #endif | 230 | #endif |
239 | 231 | ||
240 | int __devinit | 232 | int __devinit setup_niccy(struct IsdnCard *card) |
241 | setup_niccy(struct IsdnCard *card) | ||
242 | { | 233 | { |
243 | struct IsdnCardState *cs = card->cs; | 234 | struct IsdnCardState *cs = card->cs; |
244 | char tmp[64]; | 235 | char tmp[64]; |
@@ -246,40 +237,44 @@ setup_niccy(struct IsdnCard *card) | |||
246 | strcpy(tmp, niccy_revision); | 237 | strcpy(tmp, niccy_revision); |
247 | printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp)); | 238 | printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp)); |
248 | if (cs->typ != ISDN_CTYPE_NICCY) | 239 | if (cs->typ != ISDN_CTYPE_NICCY) |
249 | return (0); | 240 | return 0; |
250 | #ifdef __ISAPNP__ | 241 | #ifdef __ISAPNP__ |
251 | if (!card->para[1] && isapnp_present()) { | 242 | if (!card->para[1] && isapnp_present()) { |
252 | struct pnp_dev *pnp_d = NULL; | 243 | struct pnp_dev *pnp_d = NULL; |
253 | int err; | 244 | int err; |
254 | 245 | ||
255 | if ((pnp_c = pnp_find_card( | 246 | pnp_c = pnp_find_card(ISAPNP_VENDOR('S', 'D', 'A'), |
256 | ISAPNP_VENDOR('S', 'D', 'A'), | 247 | ISAPNP_FUNCTION(0x0150), pnp_c); |
257 | ISAPNP_FUNCTION(0x0150), pnp_c))) { | 248 | if (pnp_c) { |
258 | if (!(pnp_d = pnp_find_dev(pnp_c, | 249 | pnp_d = pnp_find_dev(pnp_c, |
259 | ISAPNP_VENDOR('S', 'D', 'A'), | 250 | ISAPNP_VENDOR('S', 'D', 'A'), |
260 | ISAPNP_FUNCTION(0x0150), pnp_d))) { | 251 | ISAPNP_FUNCTION(0x0150), pnp_d); |
261 | printk(KERN_ERR "NiccyPnP: PnP error card found, no device\n"); | 252 | if (!pnp_d) { |
262 | return (0); | 253 | printk(KERN_ERR "NiccyPnP: PnP error card " |
254 | "found, no device\n"); | ||
255 | return 0; | ||
263 | } | 256 | } |
264 | pnp_disable_dev(pnp_d); | 257 | pnp_disable_dev(pnp_d); |
265 | err = pnp_activate_dev(pnp_d); | 258 | err = pnp_activate_dev(pnp_d); |
266 | if (err<0) { | 259 | if (err < 0) { |
267 | printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", | 260 | printk(KERN_WARNING "%s: pnp_activate_dev " |
268 | __FUNCTION__, err); | 261 | "ret(%d)\n", __FUNCTION__, err); |
269 | return(0); | 262 | return 0; |
270 | } | 263 | } |
271 | card->para[1] = pnp_port_start(pnp_d, 0); | 264 | card->para[1] = pnp_port_start(pnp_d, 0); |
272 | card->para[2] = pnp_port_start(pnp_d, 1); | 265 | card->para[2] = pnp_port_start(pnp_d, 1); |
273 | card->para[0] = pnp_irq(pnp_d, 0); | 266 | card->para[0] = pnp_irq(pnp_d, 0); |
274 | if (!card->para[0] || !card->para[1] || !card->para[2]) { | 267 | if (!card->para[0] || !card->para[1] || |
275 | printk(KERN_ERR "NiccyPnP:some resources are missing %ld/%lx/%lx\n", | 268 | !card->para[2]) { |
276 | card->para[0], card->para[1], card->para[2]); | 269 | printk(KERN_ERR "NiccyPnP:some resources are " |
270 | "missing %ld/%lx/%lx\n", | ||
271 | card->para[0], card->para[1], | ||
272 | card->para[2]); | ||
277 | pnp_disable_dev(pnp_d); | 273 | pnp_disable_dev(pnp_d); |
278 | return(0); | 274 | return 0; |
279 | } | 275 | } |
280 | } else { | 276 | } else |
281 | printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n"); | 277 | printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n"); |
282 | } | ||
283 | } | 278 | } |
284 | #endif | 279 | #endif |
285 | if (card->para[1]) { | 280 | if (card->para[1]) { |
@@ -291,50 +286,51 @@ setup_niccy(struct IsdnCard *card) | |||
291 | cs->subtyp = NICCY_PNP; | 286 | cs->subtyp = NICCY_PNP; |
292 | cs->irq = card->para[0]; | 287 | cs->irq = card->para[0]; |
293 | if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { | 288 | if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { |
294 | printk(KERN_WARNING | 289 | printk(KERN_WARNING "HiSax: %s data port %x-%x " |
295 | "HiSax: %s data port %x-%x already in use\n", | 290 | "already in use\n", CardType[card->typ], |
296 | CardType[card->typ], | 291 | cs->hw.niccy.isac, cs->hw.niccy.isac + 1); |
297 | cs->hw.niccy.isac, | 292 | return 0; |
298 | cs->hw.niccy.isac + 1); | ||
299 | return (0); | ||
300 | } | 293 | } |
301 | if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) { | 294 | if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) { |
302 | printk(KERN_WARNING | 295 | printk(KERN_WARNING "HiSax: %s address port %x-%x " |
303 | "HiSax: %s address port %x-%x already in use\n", | 296 | "already in use\n", CardType[card->typ], |
304 | CardType[card->typ], | ||
305 | cs->hw.niccy.isac_ale, | 297 | cs->hw.niccy.isac_ale, |
306 | cs->hw.niccy.isac_ale + 1); | 298 | cs->hw.niccy.isac_ale + 1); |
307 | release_region(cs->hw.niccy.isac, 2); | 299 | release_region(cs->hw.niccy.isac, 2); |
308 | return (0); | 300 | return 0; |
309 | } | 301 | } |
310 | } else { | 302 | } else { |
311 | #ifdef CONFIG_PCI | 303 | #ifdef CONFIG_PCI |
312 | u_int pci_ioaddr; | 304 | u_int pci_ioaddr; |
313 | cs->subtyp = 0; | 305 | cs->subtyp = 0; |
314 | if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, | 306 | if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, |
315 | PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) { | 307 | PCI_DEVICE_ID_SATSAGEM_NICCY, |
308 | niccy_dev))) { | ||
316 | if (pci_enable_device(niccy_dev)) | 309 | if (pci_enable_device(niccy_dev)) |
317 | return(0); | 310 | return 0; |
318 | /* get IRQ */ | 311 | /* get IRQ */ |
319 | if (!niccy_dev->irq) { | 312 | if (!niccy_dev->irq) { |
320 | printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n"); | 313 | printk(KERN_WARNING |
321 | return(0); | 314 | "Niccy: No IRQ for PCI card found\n"); |
315 | return 0; | ||
322 | } | 316 | } |
323 | cs->irq = niccy_dev->irq; | 317 | cs->irq = niccy_dev->irq; |
324 | cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); | 318 | cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); |
325 | if (!cs->hw.niccy.cfg_reg) { | 319 | if (!cs->hw.niccy.cfg_reg) { |
326 | printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); | 320 | printk(KERN_WARNING |
327 | return(0); | 321 | "Niccy: No IO-Adr for PCI cfg found\n"); |
322 | return 0; | ||
328 | } | 323 | } |
329 | pci_ioaddr = pci_resource_start(niccy_dev, 1); | 324 | pci_ioaddr = pci_resource_start(niccy_dev, 1); |
330 | if (!pci_ioaddr) { | 325 | if (!pci_ioaddr) { |
331 | printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); | 326 | printk(KERN_WARNING |
332 | return(0); | 327 | "Niccy: No IO-Adr for PCI card found\n"); |
328 | return 0; | ||
333 | } | 329 | } |
334 | cs->subtyp = NICCY_PCI; | 330 | cs->subtyp = NICCY_PCI; |
335 | } else { | 331 | } else { |
336 | printk(KERN_WARNING "Niccy: No PCI card found\n"); | 332 | printk(KERN_WARNING "Niccy: No PCI card found\n"); |
337 | return(0); | 333 | return 0; |
338 | } | 334 | } |
339 | cs->irq_flags |= IRQF_SHARED; | 335 | cs->irq_flags |= IRQF_SHARED; |
340 | cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; | 336 | cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; |
@@ -343,29 +339,28 @@ setup_niccy(struct IsdnCard *card) | |||
343 | cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; | 339 | cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; |
344 | if (!request_region(cs->hw.niccy.isac, 4, "niccy")) { | 340 | if (!request_region(cs->hw.niccy.isac, 4, "niccy")) { |
345 | printk(KERN_WARNING | 341 | printk(KERN_WARNING |
346 | "HiSax: %s data port %x-%x already in use\n", | 342 | "HiSax: %s data port %x-%x already in use\n", |
347 | CardType[card->typ], | 343 | CardType[card->typ], |
348 | cs->hw.niccy.isac, | 344 | cs->hw.niccy.isac, cs->hw.niccy.isac + 4); |
349 | cs->hw.niccy.isac + 4); | 345 | return 0; |
350 | return (0); | ||
351 | } | 346 | } |
352 | if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) { | 347 | if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) { |
353 | printk(KERN_WARNING | 348 | printk(KERN_WARNING |
354 | "HiSax: %s pci port %x-%x already in use\n", | 349 | "HiSax: %s pci port %x-%x already in use\n", |
355 | CardType[card->typ], | 350 | CardType[card->typ], |
356 | cs->hw.niccy.cfg_reg, | 351 | cs->hw.niccy.cfg_reg, |
357 | cs->hw.niccy.cfg_reg + 0x40); | 352 | cs->hw.niccy.cfg_reg + 0x40); |
358 | release_region(cs->hw.niccy.isac, 4); | 353 | release_region(cs->hw.niccy.isac, 4); |
359 | return (0); | 354 | return 0; |
360 | } | 355 | } |
361 | #else | 356 | #else |
362 | printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); | 357 | printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); |
363 | printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); | 358 | printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); |
364 | return (0); | 359 | return 0; |
365 | #endif /* CONFIG_PCI */ | 360 | #endif /* CONFIG_PCI */ |
366 | } | 361 | } |
367 | printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", | 362 | printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", |
368 | CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI", | 363 | CardType[cs->typ], (cs->subtyp == 1) ? "PnP" : "PCI", |
369 | cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); | 364 | cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); |
370 | setup_isac(cs); | 365 | setup_isac(cs); |
371 | cs->readisac = &ReadISAC; | 366 | cs->readisac = &ReadISAC; |
@@ -379,10 +374,10 @@ setup_niccy(struct IsdnCard *card) | |||
379 | cs->irq_func = &niccy_interrupt; | 374 | cs->irq_func = &niccy_interrupt; |
380 | ISACVersion(cs, "Niccy:"); | 375 | ISACVersion(cs, "Niccy:"); |
381 | if (HscxVersion(cs, "Niccy:")) { | 376 | if (HscxVersion(cs, "Niccy:")) { |
382 | printk(KERN_WARNING | 377 | printk(KERN_WARNING "Niccy: wrong HSCX versions check IO " |
383 | "Niccy: wrong HSCX versions check IO address\n"); | 378 | "address\n"); |
384 | release_io_niccy(cs); | 379 | release_io_niccy(cs); |
385 | return (0); | 380 | return 0; |
386 | } | 381 | } |
387 | return (1); | 382 | return 1; |
388 | } | 383 | } |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 7fc692a8f5b..3df0e7a07c4 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -18,7 +18,7 @@ config IBM_ASM | |||
18 | service processor board as a regular serial port. To make use of | 18 | service processor board as a regular serial port. To make use of |
19 | this feature serial driver support (CONFIG_SERIAL_8250) must be | 19 | this feature serial driver support (CONFIG_SERIAL_8250) must be |
20 | enabled. | 20 | enabled. |
21 | 21 | ||
22 | WARNING: This software may not be supported or function | 22 | WARNING: This software may not be supported or function |
23 | correctly on your IBM server. Please consult the IBM ServerProven | 23 | correctly on your IBM server. Please consult the IBM ServerProven |
24 | website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for | 24 | website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for |
@@ -28,5 +28,33 @@ config IBM_ASM | |||
28 | 28 | ||
29 | If unsure, say N. | 29 | If unsure, say N. |
30 | 30 | ||
31 | endmenu | 31 | config TIFM_CORE |
32 | tristate "TI Flash Media interface support (EXPERIMENTAL)" | ||
33 | depends on EXPERIMENTAL | ||
34 | help | ||
35 | If you want support for Texas Instruments(R) Flash Media adapters | ||
36 | you should select this option and then also choose an appropriate | ||
37 | host adapter, such as 'TI Flash Media PCI74xx/PCI76xx host adapter | ||
38 | support', if you have a TI PCI74xx compatible card reader, for | ||
39 | example. | ||
40 | You will also have to select some flash card format drivers. MMC/SD | ||
41 | cards are supported via 'MMC/SD Card support: TI Flash Media MMC/SD | ||
42 | Interface support (MMC_TIFM_SD)'. | ||
43 | |||
44 | To compile this driver as a module, choose M here: the module will | ||
45 | be called tifm_core. | ||
32 | 46 | ||
47 | config TIFM_7XX1 | ||
48 | tristate "TI Flash Media PCI74xx/PCI76xx host adapter support (EXPERIMENTAL)" | ||
49 | depends on PCI && TIFM_CORE && EXPERIMENTAL | ||
50 | default TIFM_CORE | ||
51 | help | ||
52 | This option enables support for Texas Instruments(R) PCI74xx and | ||
53 | PCI76xx families of Flash Media adapters, found in many laptops. | ||
54 | To make actual use of the device, you will have to select some | ||
55 | flash card format drivers, as outlined in the TIFM_CORE Help. | ||
56 | |||
57 | To compile this driver as a module, choose M here: the module will | ||
58 | be called tifm_7xx1. | ||
59 | |||
60 | endmenu | ||
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c1bf1fb04c5..d65ece76095 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -6,3 +6,5 @@ obj- := misc.o # Dummy rule to force built-in.o to be made | |||
6 | obj-$(CONFIG_IBM_ASM) += ibmasm/ | 6 | obj-$(CONFIG_IBM_ASM) += ibmasm/ |
7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ | 7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ |
8 | obj-$(CONFIG_LKDTM) += lkdtm.o | 8 | obj-$(CONFIG_LKDTM) += lkdtm.o |
9 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o | ||
10 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o | ||
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c new file mode 100644 index 00000000000..a7ed3044618 --- /dev/null +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /* | ||
2 | * tifm_7xx1.c - TI FlashMedia driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/tifm.h> | ||
13 | #include <linux/dma-mapping.h> | ||
14 | |||
15 | #define DRIVER_NAME "tifm_7xx1" | ||
16 | #define DRIVER_VERSION "0.6" | ||
17 | |||
18 | static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) | ||
19 | { | ||
20 | int cnt; | ||
21 | unsigned long flags; | ||
22 | |||
23 | spin_lock_irqsave(&fm->lock, flags); | ||
24 | if (!fm->inhibit_new_cards) { | ||
25 | for (cnt = 0; cnt < fm->max_sockets; cnt++) { | ||
26 | if (fm->sockets[cnt] == sock) { | ||
27 | fm->remove_mask |= (1 << cnt); | ||
28 | queue_work(fm->wq, &fm->media_remover); | ||
29 | break; | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | spin_unlock_irqrestore(&fm->lock, flags); | ||
34 | } | ||
35 | |||
36 | static void tifm_7xx1_remove_media(void *adapter) | ||
37 | { | ||
38 | struct tifm_adapter *fm = adapter; | ||
39 | unsigned long flags; | ||
40 | int cnt; | ||
41 | struct tifm_dev *sock; | ||
42 | |||
43 | if (!class_device_get(&fm->cdev)) | ||
44 | return; | ||
45 | spin_lock_irqsave(&fm->lock, flags); | ||
46 | for (cnt = 0; cnt < fm->max_sockets; cnt++) { | ||
47 | if (fm->sockets[cnt] && (fm->remove_mask & (1 << cnt))) { | ||
48 | printk(KERN_INFO DRIVER_NAME | ||
49 | ": demand removing card from socket %d\n", cnt); | ||
50 | sock = fm->sockets[cnt]; | ||
51 | fm->sockets[cnt] = 0; | ||
52 | fm->remove_mask &= ~(1 << cnt); | ||
53 | |||
54 | writel(0x0e00, sock->addr + SOCK_CONTROL); | ||
55 | |||
56 | writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt, | ||
57 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
58 | writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt, | ||
59 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
60 | |||
61 | spin_unlock_irqrestore(&fm->lock, flags); | ||
62 | device_unregister(&sock->dev); | ||
63 | spin_lock_irqsave(&fm->lock, flags); | ||
64 | } | ||
65 | } | ||
66 | spin_unlock_irqrestore(&fm->lock, flags); | ||
67 | class_device_put(&fm->cdev); | ||
68 | } | ||
69 | |||
70 | static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs) | ||
71 | { | ||
72 | struct tifm_adapter *fm = dev_id; | ||
73 | unsigned int irq_status; | ||
74 | unsigned int sock_irq_status, cnt; | ||
75 | |||
76 | spin_lock(&fm->lock); | ||
77 | irq_status = readl(fm->addr + FM_INTERRUPT_STATUS); | ||
78 | if (irq_status == 0 || irq_status == (~0)) { | ||
79 | spin_unlock(&fm->lock); | ||
80 | return IRQ_NONE; | ||
81 | } | ||
82 | |||
83 | if (irq_status & TIFM_IRQ_ENABLE) { | ||
84 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
85 | |||
86 | for (cnt = 0; cnt < fm->max_sockets; cnt++) { | ||
87 | sock_irq_status = (irq_status >> cnt) & | ||
88 | (TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK); | ||
89 | |||
90 | if (fm->sockets[cnt]) { | ||
91 | if (sock_irq_status && | ||
92 | fm->sockets[cnt]->signal_irq) | ||
93 | sock_irq_status = fm->sockets[cnt]-> | ||
94 | signal_irq(fm->sockets[cnt], | ||
95 | sock_irq_status); | ||
96 | |||
97 | if (irq_status & (1 << cnt)) | ||
98 | fm->remove_mask |= 1 << cnt; | ||
99 | } else { | ||
100 | if (irq_status & (1 << cnt)) | ||
101 | fm->insert_mask |= 1 << cnt; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | writel(irq_status, fm->addr + FM_INTERRUPT_STATUS); | ||
106 | |||
107 | if (!fm->inhibit_new_cards) { | ||
108 | if (!fm->remove_mask && !fm->insert_mask) { | ||
109 | writel(TIFM_IRQ_ENABLE, | ||
110 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
111 | } else { | ||
112 | queue_work(fm->wq, &fm->media_remover); | ||
113 | queue_work(fm->wq, &fm->media_inserter); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | spin_unlock(&fm->lock); | ||
118 | return IRQ_HANDLED; | ||
119 | } | ||
120 | |||
121 | static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2) | ||
122 | { | ||
123 | unsigned int s_state; | ||
124 | int cnt; | ||
125 | |||
126 | writel(0x0e00, sock_addr + SOCK_CONTROL); | ||
127 | |||
128 | for (cnt = 0; cnt < 100; cnt++) { | ||
129 | if (!(TIFM_SOCK_STATE_POWERED & | ||
130 | readl(sock_addr + SOCK_PRESENT_STATE))) | ||
131 | break; | ||
132 | msleep(10); | ||
133 | } | ||
134 | |||
135 | s_state = readl(sock_addr + SOCK_PRESENT_STATE); | ||
136 | if (!(TIFM_SOCK_STATE_OCCUPIED & s_state)) | ||
137 | return FM_NULL; | ||
138 | |||
139 | if (is_x2) { | ||
140 | writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); | ||
141 | } else { | ||
142 | // SmartMedia cards need extra 40 msec | ||
143 | if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1) | ||
144 | msleep(40); | ||
145 | writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED, | ||
146 | sock_addr + SOCK_CONTROL); | ||
147 | msleep(10); | ||
148 | writel((s_state & 0x7) | 0x0c00 | TIFM_CTRL_LED, | ||
149 | sock_addr + SOCK_CONTROL); | ||
150 | } | ||
151 | |||
152 | for (cnt = 0; cnt < 100; cnt++) { | ||
153 | if ((TIFM_SOCK_STATE_POWERED & | ||
154 | readl(sock_addr + SOCK_PRESENT_STATE))) | ||
155 | break; | ||
156 | msleep(10); | ||
157 | } | ||
158 | |||
159 | if (!is_x2) | ||
160 | writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED), | ||
161 | sock_addr + SOCK_CONTROL); | ||
162 | |||
163 | return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; | ||
164 | } | ||
165 | |||
166 | inline static char *tifm_7xx1_sock_addr(char *base_addr, unsigned int sock_num) | ||
167 | { | ||
168 | return base_addr + ((sock_num + 1) << 10); | ||
169 | } | ||
170 | |||
171 | static void tifm_7xx1_insert_media(void *adapter) | ||
172 | { | ||
173 | struct tifm_adapter *fm = adapter; | ||
174 | unsigned long flags; | ||
175 | tifm_media_id media_id; | ||
176 | char *card_name = "xx"; | ||
177 | int cnt, ok_to_register; | ||
178 | unsigned int insert_mask; | ||
179 | struct tifm_dev *new_sock = 0; | ||
180 | |||
181 | if (!class_device_get(&fm->cdev)) | ||
182 | return; | ||
183 | spin_lock_irqsave(&fm->lock, flags); | ||
184 | insert_mask = fm->insert_mask; | ||
185 | fm->insert_mask = 0; | ||
186 | if (fm->inhibit_new_cards) { | ||
187 | spin_unlock_irqrestore(&fm->lock, flags); | ||
188 | class_device_put(&fm->cdev); | ||
189 | return; | ||
190 | } | ||
191 | spin_unlock_irqrestore(&fm->lock, flags); | ||
192 | |||
193 | for (cnt = 0; cnt < fm->max_sockets; cnt++) { | ||
194 | if (!(insert_mask & (1 << cnt))) | ||
195 | continue; | ||
196 | |||
197 | media_id = tifm_7xx1_toggle_sock_power(tifm_7xx1_sock_addr(fm->addr, cnt), | ||
198 | fm->max_sockets == 2); | ||
199 | if (media_id) { | ||
200 | ok_to_register = 0; | ||
201 | new_sock = tifm_alloc_device(fm, cnt); | ||
202 | if (new_sock) { | ||
203 | new_sock->addr = tifm_7xx1_sock_addr(fm->addr, | ||
204 | cnt); | ||
205 | new_sock->media_id = media_id; | ||
206 | switch (media_id) { | ||
207 | case 1: | ||
208 | card_name = "xd"; | ||
209 | break; | ||
210 | case 2: | ||
211 | card_name = "ms"; | ||
212 | break; | ||
213 | case 3: | ||
214 | card_name = "sd"; | ||
215 | break; | ||
216 | default: | ||
217 | break; | ||
218 | } | ||
219 | snprintf(new_sock->dev.bus_id, BUS_ID_SIZE, | ||
220 | "tifm_%s%u:%u", card_name, fm->id, cnt); | ||
221 | printk(KERN_INFO DRIVER_NAME | ||
222 | ": %s card detected in socket %d\n", | ||
223 | card_name, cnt); | ||
224 | spin_lock_irqsave(&fm->lock, flags); | ||
225 | if (!fm->sockets[cnt]) { | ||
226 | fm->sockets[cnt] = new_sock; | ||
227 | ok_to_register = 1; | ||
228 | } | ||
229 | spin_unlock_irqrestore(&fm->lock, flags); | ||
230 | if (!ok_to_register || | ||
231 | device_register(&new_sock->dev)) { | ||
232 | spin_lock_irqsave(&fm->lock, flags); | ||
233 | fm->sockets[cnt] = 0; | ||
234 | spin_unlock_irqrestore(&fm->lock, | ||
235 | flags); | ||
236 | tifm_free_device(&new_sock->dev); | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt, | ||
241 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
242 | writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt, | ||
243 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
244 | } | ||
245 | |||
246 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
247 | class_device_put(&fm->cdev); | ||
248 | } | ||
249 | |||
250 | static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) | ||
251 | { | ||
252 | struct tifm_adapter *fm = pci_get_drvdata(dev); | ||
253 | unsigned long flags; | ||
254 | |||
255 | spin_lock_irqsave(&fm->lock, flags); | ||
256 | fm->inhibit_new_cards = 1; | ||
257 | fm->remove_mask = 0xf; | ||
258 | fm->insert_mask = 0; | ||
259 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
260 | spin_unlock_irqrestore(&fm->lock, flags); | ||
261 | flush_workqueue(fm->wq); | ||
262 | |||
263 | tifm_7xx1_remove_media(fm); | ||
264 | |||
265 | pci_set_power_state(dev, PCI_D3hot); | ||
266 | pci_disable_device(dev); | ||
267 | pci_save_state(dev); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int tifm_7xx1_resume(struct pci_dev *dev) | ||
272 | { | ||
273 | struct tifm_adapter *fm = pci_get_drvdata(dev); | ||
274 | unsigned long flags; | ||
275 | |||
276 | pci_restore_state(dev); | ||
277 | pci_enable_device(dev); | ||
278 | pci_set_power_state(dev, PCI_D0); | ||
279 | pci_set_master(dev); | ||
280 | |||
281 | spin_lock_irqsave(&fm->lock, flags); | ||
282 | fm->inhibit_new_cards = 0; | ||
283 | writel(TIFM_IRQ_SETALL, fm->addr + FM_INTERRUPT_STATUS); | ||
284 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
285 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK, | ||
286 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
287 | fm->insert_mask = 0xf; | ||
288 | spin_unlock_irqrestore(&fm->lock, flags); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int tifm_7xx1_probe(struct pci_dev *dev, | ||
293 | const struct pci_device_id *dev_id) | ||
294 | { | ||
295 | struct tifm_adapter *fm; | ||
296 | int pci_dev_busy = 0; | ||
297 | int rc; | ||
298 | |||
299 | rc = pci_set_dma_mask(dev, DMA_32BIT_MASK); | ||
300 | if (rc) | ||
301 | return rc; | ||
302 | |||
303 | rc = pci_enable_device(dev); | ||
304 | if (rc) | ||
305 | return rc; | ||
306 | |||
307 | pci_set_master(dev); | ||
308 | |||
309 | rc = pci_request_regions(dev, DRIVER_NAME); | ||
310 | if (rc) { | ||
311 | pci_dev_busy = 1; | ||
312 | goto err_out; | ||
313 | } | ||
314 | |||
315 | pci_intx(dev, 1); | ||
316 | |||
317 | fm = tifm_alloc_adapter(); | ||
318 | if (!fm) { | ||
319 | rc = -ENOMEM; | ||
320 | goto err_out_int; | ||
321 | } | ||
322 | |||
323 | fm->dev = &dev->dev; | ||
324 | fm->max_sockets = (dev->device == 0x803B) ? 2 : 4; | ||
325 | fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->max_sockets, | ||
326 | GFP_KERNEL); | ||
327 | if (!fm->sockets) | ||
328 | goto err_out_free; | ||
329 | |||
330 | INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media, fm); | ||
331 | INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media, fm); | ||
332 | fm->eject = tifm_7xx1_eject; | ||
333 | pci_set_drvdata(dev, fm); | ||
334 | |||
335 | fm->addr = ioremap(pci_resource_start(dev, 0), | ||
336 | pci_resource_len(dev, 0)); | ||
337 | if (!fm->addr) | ||
338 | goto err_out_free; | ||
339 | |||
340 | rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm); | ||
341 | if (rc) | ||
342 | goto err_out_unmap; | ||
343 | |||
344 | rc = tifm_add_adapter(fm); | ||
345 | if (rc) | ||
346 | goto err_out_irq; | ||
347 | |||
348 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
349 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK, | ||
350 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
351 | |||
352 | fm->insert_mask = 0xf; | ||
353 | |||
354 | return 0; | ||
355 | |||
356 | err_out_irq: | ||
357 | free_irq(dev->irq, fm); | ||
358 | err_out_unmap: | ||
359 | iounmap(fm->addr); | ||
360 | err_out_free: | ||
361 | pci_set_drvdata(dev, NULL); | ||
362 | tifm_free_adapter(fm); | ||
363 | err_out_int: | ||
364 | pci_intx(dev, 0); | ||
365 | pci_release_regions(dev); | ||
366 | err_out: | ||
367 | if (!pci_dev_busy) | ||
368 | pci_disable_device(dev); | ||
369 | return rc; | ||
370 | } | ||
371 | |||
372 | static void tifm_7xx1_remove(struct pci_dev *dev) | ||
373 | { | ||
374 | struct tifm_adapter *fm = pci_get_drvdata(dev); | ||
375 | unsigned long flags; | ||
376 | |||
377 | spin_lock_irqsave(&fm->lock, flags); | ||
378 | fm->inhibit_new_cards = 1; | ||
379 | fm->remove_mask = 0xf; | ||
380 | fm->insert_mask = 0; | ||
381 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
382 | spin_unlock_irqrestore(&fm->lock, flags); | ||
383 | |||
384 | flush_workqueue(fm->wq); | ||
385 | |||
386 | tifm_7xx1_remove_media(fm); | ||
387 | |||
388 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
389 | free_irq(dev->irq, fm); | ||
390 | |||
391 | tifm_remove_adapter(fm); | ||
392 | |||
393 | pci_set_drvdata(dev, 0); | ||
394 | |||
395 | iounmap(fm->addr); | ||
396 | pci_intx(dev, 0); | ||
397 | pci_release_regions(dev); | ||
398 | |||
399 | pci_disable_device(dev); | ||
400 | tifm_free_adapter(fm); | ||
401 | } | ||
402 | |||
403 | static struct pci_device_id tifm_7xx1_pci_tbl [] = { | ||
404 | { PCI_VENDOR_ID_TI, 0x8033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
405 | 0 }, /* xx21 - the one I have */ | ||
406 | { PCI_VENDOR_ID_TI, 0x803B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
407 | 0 }, /* xx12 - should be also supported */ | ||
408 | { } | ||
409 | }; | ||
410 | |||
411 | static struct pci_driver tifm_7xx1_driver = { | ||
412 | .name = DRIVER_NAME, | ||
413 | .id_table = tifm_7xx1_pci_tbl, | ||
414 | .probe = tifm_7xx1_probe, | ||
415 | .remove = tifm_7xx1_remove, | ||
416 | .suspend = tifm_7xx1_suspend, | ||
417 | .resume = tifm_7xx1_resume, | ||
418 | }; | ||
419 | |||
420 | static int __init tifm_7xx1_init(void) | ||
421 | { | ||
422 | return pci_register_driver(&tifm_7xx1_driver); | ||
423 | } | ||
424 | |||
425 | static void __exit tifm_7xx1_exit(void) | ||
426 | { | ||
427 | pci_unregister_driver(&tifm_7xx1_driver); | ||
428 | } | ||
429 | |||
430 | MODULE_AUTHOR("Alex Dubov"); | ||
431 | MODULE_DESCRIPTION("TI FlashMedia host driver"); | ||
432 | MODULE_LICENSE("GPL"); | ||
433 | MODULE_DEVICE_TABLE(pci, tifm_7xx1_pci_tbl); | ||
434 | MODULE_VERSION(DRIVER_VERSION); | ||
435 | |||
436 | module_init(tifm_7xx1_init); | ||
437 | module_exit(tifm_7xx1_exit); | ||
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c new file mode 100644 index 00000000000..cca5f852246 --- /dev/null +++ b/drivers/misc/tifm_core.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * tifm_core.c - TI FlashMedia driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/tifm.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/idr.h> | ||
15 | |||
16 | #define DRIVER_NAME "tifm_core" | ||
17 | #define DRIVER_VERSION "0.6" | ||
18 | |||
19 | static DEFINE_IDR(tifm_adapter_idr); | ||
20 | static DEFINE_SPINLOCK(tifm_adapter_lock); | ||
21 | |||
22 | static tifm_media_id *tifm_device_match(tifm_media_id *ids, | ||
23 | struct tifm_dev *dev) | ||
24 | { | ||
25 | while (*ids) { | ||
26 | if (dev->media_id == *ids) | ||
27 | return ids; | ||
28 | ids++; | ||
29 | } | ||
30 | return NULL; | ||
31 | } | ||
32 | |||
33 | static int tifm_match(struct device *dev, struct device_driver *drv) | ||
34 | { | ||
35 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | ||
36 | struct tifm_driver *fm_drv; | ||
37 | |||
38 | fm_drv = container_of(drv, struct tifm_driver, driver); | ||
39 | if (!fm_drv->id_table) | ||
40 | return -EINVAL; | ||
41 | if (tifm_device_match(fm_drv->id_table, fm_dev)) | ||
42 | return 1; | ||
43 | return -ENODEV; | ||
44 | } | ||
45 | |||
46 | static int tifm_uevent(struct device *dev, char **envp, int num_envp, | ||
47 | char *buffer, int buffer_size) | ||
48 | { | ||
49 | struct tifm_dev *fm_dev; | ||
50 | int i = 0; | ||
51 | int length = 0; | ||
52 | const char *card_type_name[] = {"INV", "SM", "MS", "SD"}; | ||
53 | |||
54 | if (!dev || !(fm_dev = container_of(dev, struct tifm_dev, dev))) | ||
55 | return -ENODEV; | ||
56 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | ||
57 | "TIFM_CARD_TYPE=%s", card_type_name[fm_dev->media_id])) | ||
58 | return -ENOMEM; | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static struct bus_type tifm_bus_type = { | ||
64 | .name = "tifm", | ||
65 | .match = tifm_match, | ||
66 | .uevent = tifm_uevent, | ||
67 | }; | ||
68 | |||
69 | static void tifm_free(struct class_device *cdev) | ||
70 | { | ||
71 | struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev); | ||
72 | |||
73 | kfree(fm->sockets); | ||
74 | if (fm->wq) | ||
75 | destroy_workqueue(fm->wq); | ||
76 | kfree(fm); | ||
77 | } | ||
78 | |||
79 | static struct class tifm_adapter_class = { | ||
80 | .name = "tifm_adapter", | ||
81 | .release = tifm_free | ||
82 | }; | ||
83 | |||
84 | struct tifm_adapter *tifm_alloc_adapter(void) | ||
85 | { | ||
86 | struct tifm_adapter *fm; | ||
87 | |||
88 | fm = kzalloc(sizeof(struct tifm_adapter), GFP_KERNEL); | ||
89 | if (fm) { | ||
90 | fm->cdev.class = &tifm_adapter_class; | ||
91 | spin_lock_init(&fm->lock); | ||
92 | class_device_initialize(&fm->cdev); | ||
93 | } | ||
94 | return fm; | ||
95 | } | ||
96 | EXPORT_SYMBOL(tifm_alloc_adapter); | ||
97 | |||
98 | void tifm_free_adapter(struct tifm_adapter *fm) | ||
99 | { | ||
100 | class_device_put(&fm->cdev); | ||
101 | } | ||
102 | EXPORT_SYMBOL(tifm_free_adapter); | ||
103 | |||
104 | int tifm_add_adapter(struct tifm_adapter *fm) | ||
105 | { | ||
106 | int rc; | ||
107 | |||
108 | if (!idr_pre_get(&tifm_adapter_idr, GFP_KERNEL)) | ||
109 | return -ENOMEM; | ||
110 | |||
111 | spin_lock(&tifm_adapter_lock); | ||
112 | rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id); | ||
113 | spin_unlock(&tifm_adapter_lock); | ||
114 | if (!rc) { | ||
115 | snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); | ||
116 | strncpy(fm->wq_name, fm->cdev.class_id, KOBJ_NAME_LEN); | ||
117 | |||
118 | fm->wq = create_singlethread_workqueue(fm->wq_name); | ||
119 | if (fm->wq) | ||
120 | return class_device_add(&fm->cdev); | ||
121 | |||
122 | spin_lock(&tifm_adapter_lock); | ||
123 | idr_remove(&tifm_adapter_idr, fm->id); | ||
124 | spin_unlock(&tifm_adapter_lock); | ||
125 | rc = -ENOMEM; | ||
126 | } | ||
127 | return rc; | ||
128 | } | ||
129 | EXPORT_SYMBOL(tifm_add_adapter); | ||
130 | |||
131 | void tifm_remove_adapter(struct tifm_adapter *fm) | ||
132 | { | ||
133 | class_device_del(&fm->cdev); | ||
134 | |||
135 | spin_lock(&tifm_adapter_lock); | ||
136 | idr_remove(&tifm_adapter_idr, fm->id); | ||
137 | spin_unlock(&tifm_adapter_lock); | ||
138 | } | ||
139 | EXPORT_SYMBOL(tifm_remove_adapter); | ||
140 | |||
141 | void tifm_free_device(struct device *dev) | ||
142 | { | ||
143 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | ||
144 | if (fm_dev->wq) | ||
145 | destroy_workqueue(fm_dev->wq); | ||
146 | kfree(fm_dev); | ||
147 | } | ||
148 | EXPORT_SYMBOL(tifm_free_device); | ||
149 | |||
150 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) | ||
151 | { | ||
152 | struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); | ||
153 | |||
154 | if (dev) { | ||
155 | spin_lock_init(&dev->lock); | ||
156 | snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id); | ||
157 | dev->wq = create_singlethread_workqueue(dev->wq_name); | ||
158 | if (!dev->wq) { | ||
159 | kfree(dev); | ||
160 | return 0; | ||
161 | } | ||
162 | dev->dev.parent = fm->dev; | ||
163 | dev->dev.bus = &tifm_bus_type; | ||
164 | dev->dev.release = tifm_free_device; | ||
165 | } | ||
166 | return dev; | ||
167 | } | ||
168 | EXPORT_SYMBOL(tifm_alloc_device); | ||
169 | |||
170 | void tifm_eject(struct tifm_dev *sock) | ||
171 | { | ||
172 | struct tifm_adapter *fm = dev_get_drvdata(sock->dev.parent); | ||
173 | fm->eject(fm, sock); | ||
174 | } | ||
175 | EXPORT_SYMBOL(tifm_eject); | ||
176 | |||
177 | int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, | ||
178 | int direction) | ||
179 | { | ||
180 | return pci_map_sg(to_pci_dev(sock->dev.parent), sg, nents, direction); | ||
181 | } | ||
182 | EXPORT_SYMBOL(tifm_map_sg); | ||
183 | |||
184 | void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, | ||
185 | int direction) | ||
186 | { | ||
187 | pci_unmap_sg(to_pci_dev(sock->dev.parent), sg, nents, direction); | ||
188 | } | ||
189 | EXPORT_SYMBOL(tifm_unmap_sg); | ||
190 | |||
191 | static int tifm_device_probe(struct device *dev) | ||
192 | { | ||
193 | struct tifm_driver *drv; | ||
194 | struct tifm_dev *fm_dev; | ||
195 | int rc = 0; | ||
196 | const tifm_media_id *id; | ||
197 | |||
198 | drv = container_of(dev->driver, struct tifm_driver, driver); | ||
199 | fm_dev = container_of(dev, struct tifm_dev, dev); | ||
200 | get_device(dev); | ||
201 | if (!fm_dev->drv && drv->probe && drv->id_table) { | ||
202 | rc = -ENODEV; | ||
203 | id = tifm_device_match(drv->id_table, fm_dev); | ||
204 | if (id) | ||
205 | rc = drv->probe(fm_dev); | ||
206 | if (rc >= 0) { | ||
207 | rc = 0; | ||
208 | fm_dev->drv = drv; | ||
209 | } | ||
210 | } | ||
211 | if (rc) | ||
212 | put_device(dev); | ||
213 | return rc; | ||
214 | } | ||
215 | |||
216 | static int tifm_device_remove(struct device *dev) | ||
217 | { | ||
218 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | ||
219 | struct tifm_driver *drv = fm_dev->drv; | ||
220 | |||
221 | if (drv) { | ||
222 | if (drv->remove) drv->remove(fm_dev); | ||
223 | fm_dev->drv = 0; | ||
224 | } | ||
225 | |||
226 | put_device(dev); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | int tifm_register_driver(struct tifm_driver *drv) | ||
231 | { | ||
232 | drv->driver.bus = &tifm_bus_type; | ||
233 | drv->driver.probe = tifm_device_probe; | ||
234 | drv->driver.remove = tifm_device_remove; | ||
235 | |||
236 | return driver_register(&drv->driver); | ||
237 | } | ||
238 | EXPORT_SYMBOL(tifm_register_driver); | ||
239 | |||
240 | void tifm_unregister_driver(struct tifm_driver *drv) | ||
241 | { | ||
242 | driver_unregister(&drv->driver); | ||
243 | } | ||
244 | EXPORT_SYMBOL(tifm_unregister_driver); | ||
245 | |||
246 | static int __init tifm_init(void) | ||
247 | { | ||
248 | int rc = bus_register(&tifm_bus_type); | ||
249 | |||
250 | if (!rc) { | ||
251 | rc = class_register(&tifm_adapter_class); | ||
252 | if (rc) | ||
253 | bus_unregister(&tifm_bus_type); | ||
254 | } | ||
255 | |||
256 | return rc; | ||
257 | } | ||
258 | |||
259 | static void __exit tifm_exit(void) | ||
260 | { | ||
261 | class_unregister(&tifm_adapter_class); | ||
262 | bus_unregister(&tifm_bus_type); | ||
263 | } | ||
264 | |||
265 | subsys_initcall(tifm_init); | ||
266 | module_exit(tifm_exit); | ||
267 | |||
268 | MODULE_LICENSE("GPL"); | ||
269 | MODULE_AUTHOR("Alex Dubov"); | ||
270 | MODULE_DESCRIPTION("TI FlashMedia core driver"); | ||
271 | MODULE_LICENSE("GPL"); | ||
272 | MODULE_VERSION(DRIVER_VERSION); | ||
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index f540bd88dc5..ea41852ec8c 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -109,4 +109,20 @@ config MMC_IMX | |||
109 | 109 | ||
110 | If unsure, say N. | 110 | If unsure, say N. |
111 | 111 | ||
112 | config MMC_TIFM_SD | ||
113 | tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" | ||
114 | depends on MMC && EXPERIMENTAL | ||
115 | select TIFM_CORE | ||
116 | help | ||
117 | Say Y here if you want to be able to access MMC/SD cards with | ||
118 | the Texas Instruments(R) Flash Media card reader, found in many | ||
119 | laptops. | ||
120 | This option 'selects' (turns on, enables) 'TIFM_CORE', but you | ||
121 | probably also need appropriate card reader host adapter, such as | ||
122 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support | ||
123 | (TIFM_7XX1)'. | ||
124 | |||
125 | To compile this driver as a module, choose M here: the | ||
126 | module will be called tifm_sd. | ||
127 | |||
112 | endmenu | 128 | endmenu |
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index b1f6e03e7aa..acfd4de0aba 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_MMC_WBSD) += wbsd.o | |||
23 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o | 23 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o |
24 | obj-$(CONFIG_MMC_OMAP) += omap.o | 24 | obj-$(CONFIG_MMC_OMAP) += omap.o |
25 | obj-$(CONFIG_MMC_AT91RM9200) += at91_mci.o | 25 | obj-$(CONFIG_MMC_AT91RM9200) += at91_mci.o |
26 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | ||
26 | 27 | ||
27 | mmc_core-y := mmc.o mmc_sysfs.o | 28 | mmc_core-y := mmc.o mmc_sysfs.o |
28 | mmc_core-$(CONFIG_BLOCK) += mmc_queue.o | 29 | mmc_core-$(CONFIG_BLOCK) += mmc_queue.o |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 5b9caa7978d..ee8863c123e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -1166,9 +1166,9 @@ static void mmc_setup(struct mmc_host *host) | |||
1166 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | 1166 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) |
1167 | { | 1167 | { |
1168 | if (delay) | 1168 | if (delay) |
1169 | schedule_delayed_work(&host->detect, delay); | 1169 | mmc_schedule_delayed_work(&host->detect, delay); |
1170 | else | 1170 | else |
1171 | schedule_work(&host->detect); | 1171 | mmc_schedule_work(&host->detect); |
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | EXPORT_SYMBOL(mmc_detect_change); | 1174 | EXPORT_SYMBOL(mmc_detect_change); |
@@ -1311,7 +1311,7 @@ EXPORT_SYMBOL(mmc_remove_host); | |||
1311 | */ | 1311 | */ |
1312 | void mmc_free_host(struct mmc_host *host) | 1312 | void mmc_free_host(struct mmc_host *host) |
1313 | { | 1313 | { |
1314 | flush_scheduled_work(); | 1314 | mmc_flush_scheduled_work(); |
1315 | mmc_free_host_sysfs(host); | 1315 | mmc_free_host_sysfs(host); |
1316 | } | 1316 | } |
1317 | 1317 | ||
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/mmc.h index 97bae00292f..cd5e0ab3d84 100644 --- a/drivers/mmc/mmc.h +++ b/drivers/mmc/mmc.h | |||
@@ -18,4 +18,8 @@ struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev); | |||
18 | int mmc_add_host_sysfs(struct mmc_host *host); | 18 | int mmc_add_host_sysfs(struct mmc_host *host); |
19 | void mmc_remove_host_sysfs(struct mmc_host *host); | 19 | void mmc_remove_host_sysfs(struct mmc_host *host); |
20 | void mmc_free_host_sysfs(struct mmc_host *host); | 20 | void mmc_free_host_sysfs(struct mmc_host *host); |
21 | |||
22 | int mmc_schedule_work(struct work_struct *work); | ||
23 | int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay); | ||
24 | void mmc_flush_scheduled_work(void); | ||
21 | #endif | 25 | #endif |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index db0e8ad439a..c1293f1bda8 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
@@ -158,13 +158,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
158 | { | 158 | { |
159 | struct mmc_blk_data *md = mq->data; | 159 | struct mmc_blk_data *md = mq->data; |
160 | struct mmc_card *card = md->queue.card; | 160 | struct mmc_card *card = md->queue.card; |
161 | struct mmc_blk_request brq; | ||
161 | int ret; | 162 | int ret; |
162 | 163 | ||
163 | if (mmc_card_claim_host(card)) | 164 | if (mmc_card_claim_host(card)) |
164 | goto cmd_err; | 165 | goto cmd_err; |
165 | 166 | ||
166 | do { | 167 | do { |
167 | struct mmc_blk_request brq; | ||
168 | struct mmc_command cmd; | 168 | struct mmc_command cmd; |
169 | u32 readcmd, writecmd; | 169 | u32 readcmd, writecmd; |
170 | 170 | ||
@@ -278,17 +278,27 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
278 | cmd_err: | 278 | cmd_err: |
279 | mmc_card_release_host(card); | 279 | mmc_card_release_host(card); |
280 | 280 | ||
281 | ret = 1; | ||
282 | |||
281 | /* | 283 | /* |
282 | * This is a little draconian, but until we get proper | 284 | * For writes and where the host claims to support proper |
283 | * error handling sorted out here, its the best we can | 285 | * error reporting, we first ok the successful blocks. |
284 | * do - especially as some hosts have no idea how much | 286 | * |
285 | * data was transferred before the error occurred. | 287 | * For reads we just fail the entire chunk as that should |
288 | * be safe in all cases. | ||
286 | */ | 289 | */ |
290 | if (rq_data_dir(req) != READ && | ||
291 | (card->host->caps & MMC_CAP_MULTIWRITE)) { | ||
292 | spin_lock_irq(&md->lock); | ||
293 | ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); | ||
294 | spin_unlock_irq(&md->lock); | ||
295 | } | ||
296 | |||
287 | spin_lock_irq(&md->lock); | 297 | spin_lock_irq(&md->lock); |
288 | do { | 298 | while (ret) { |
289 | ret = end_that_request_chunk(req, 0, | 299 | ret = end_that_request_chunk(req, 0, |
290 | req->current_nr_sectors << 9); | 300 | req->current_nr_sectors << 9); |
291 | } while (ret); | 301 | } |
292 | 302 | ||
293 | add_disk_randomness(req->rq_disk); | 303 | add_disk_randomness(req->rq_disk); |
294 | blkdev_dequeue_request(req); | 304 | blkdev_dequeue_request(req); |
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c index a2a35fd946e..10cc9734eaa 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/mmc_sysfs.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/idr.h> | 15 | #include <linux/idr.h> |
16 | #include <linux/workqueue.h> | ||
16 | 17 | ||
17 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
18 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
@@ -317,10 +318,41 @@ void mmc_free_host_sysfs(struct mmc_host *host) | |||
317 | class_device_put(&host->class_dev); | 318 | class_device_put(&host->class_dev); |
318 | } | 319 | } |
319 | 320 | ||
321 | static struct workqueue_struct *workqueue; | ||
322 | |||
323 | /* | ||
324 | * Internal function. Schedule work in the MMC work queue. | ||
325 | */ | ||
326 | int mmc_schedule_work(struct work_struct *work) | ||
327 | { | ||
328 | return queue_work(workqueue, work); | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Internal function. Schedule delayed work in the MMC work queue. | ||
333 | */ | ||
334 | int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay) | ||
335 | { | ||
336 | return queue_delayed_work(workqueue, work, delay); | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * Internal function. Flush all scheduled work from the MMC work queue. | ||
341 | */ | ||
342 | void mmc_flush_scheduled_work(void) | ||
343 | { | ||
344 | flush_workqueue(workqueue); | ||
345 | } | ||
320 | 346 | ||
321 | static int __init mmc_init(void) | 347 | static int __init mmc_init(void) |
322 | { | 348 | { |
323 | int ret = bus_register(&mmc_bus_type); | 349 | int ret; |
350 | |||
351 | workqueue = create_singlethread_workqueue("kmmcd"); | ||
352 | if (!workqueue) | ||
353 | return -ENOMEM; | ||
354 | |||
355 | ret = bus_register(&mmc_bus_type); | ||
324 | if (ret == 0) { | 356 | if (ret == 0) { |
325 | ret = class_register(&mmc_host_class); | 357 | ret = class_register(&mmc_host_class); |
326 | if (ret) | 358 | if (ret) |
@@ -333,6 +365,7 @@ static void __exit mmc_exit(void) | |||
333 | { | 365 | { |
334 | class_unregister(&mmc_host_class); | 366 | class_unregister(&mmc_host_class); |
335 | bus_unregister(&mmc_bus_type); | 367 | bus_unregister(&mmc_bus_type); |
368 | destroy_workqueue(workqueue); | ||
336 | } | 369 | } |
337 | 370 | ||
338 | module_init(mmc_init); | 371 | module_init(mmc_init); |
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 4dab5ec392e..20711acb012 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c | |||
@@ -35,6 +35,8 @@ static unsigned int debug_quirks = 0; | |||
35 | 35 | ||
36 | #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) | 36 | #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) |
37 | #define SDHCI_QUIRK_FORCE_DMA (1<<1) | 37 | #define SDHCI_QUIRK_FORCE_DMA (1<<1) |
38 | /* Controller doesn't like some resets when there is no card inserted. */ | ||
39 | #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) | ||
38 | 40 | ||
39 | static const struct pci_device_id pci_ids[] __devinitdata = { | 41 | static const struct pci_device_id pci_ids[] __devinitdata = { |
40 | { | 42 | { |
@@ -51,7 +53,8 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
51 | .device = PCI_DEVICE_ID_RICOH_R5C822, | 53 | .device = PCI_DEVICE_ID_RICOH_R5C822, |
52 | .subvendor = PCI_ANY_ID, | 54 | .subvendor = PCI_ANY_ID, |
53 | .subdevice = PCI_ANY_ID, | 55 | .subdevice = PCI_ANY_ID, |
54 | .driver_data = SDHCI_QUIRK_FORCE_DMA, | 56 | .driver_data = SDHCI_QUIRK_FORCE_DMA | |
57 | SDHCI_QUIRK_NO_CARD_NO_RESET, | ||
55 | }, | 58 | }, |
56 | 59 | ||
57 | { | 60 | { |
@@ -125,6 +128,12 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
125 | { | 128 | { |
126 | unsigned long timeout; | 129 | unsigned long timeout; |
127 | 130 | ||
131 | if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { | ||
132 | if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & | ||
133 | SDHCI_CARD_PRESENT)) | ||
134 | return; | ||
135 | } | ||
136 | |||
128 | writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); | 137 | writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); |
129 | 138 | ||
130 | if (mask & SDHCI_RESET_ALL) | 139 | if (mask & SDHCI_RESET_ALL) |
@@ -717,6 +726,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
717 | } else | 726 | } else |
718 | sdhci_send_command(host, mrq->cmd); | 727 | sdhci_send_command(host, mrq->cmd); |
719 | 728 | ||
729 | mmiowb(); | ||
720 | spin_unlock_irqrestore(&host->lock, flags); | 730 | spin_unlock_irqrestore(&host->lock, flags); |
721 | } | 731 | } |
722 | 732 | ||
@@ -753,6 +763,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
753 | ctrl &= ~SDHCI_CTRL_4BITBUS; | 763 | ctrl &= ~SDHCI_CTRL_4BITBUS; |
754 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); | 764 | writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); |
755 | 765 | ||
766 | mmiowb(); | ||
756 | spin_unlock_irqrestore(&host->lock, flags); | 767 | spin_unlock_irqrestore(&host->lock, flags); |
757 | } | 768 | } |
758 | 769 | ||
@@ -860,6 +871,7 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
860 | 871 | ||
861 | sdhci_deactivate_led(host); | 872 | sdhci_deactivate_led(host); |
862 | 873 | ||
874 | mmiowb(); | ||
863 | spin_unlock_irqrestore(&host->lock, flags); | 875 | spin_unlock_irqrestore(&host->lock, flags); |
864 | 876 | ||
865 | mmc_request_done(host->mmc, mrq); | 877 | mmc_request_done(host->mmc, mrq); |
@@ -893,6 +905,7 @@ static void sdhci_timeout_timer(unsigned long data) | |||
893 | } | 905 | } |
894 | } | 906 | } |
895 | 907 | ||
908 | mmiowb(); | ||
896 | spin_unlock_irqrestore(&host->lock, flags); | 909 | spin_unlock_irqrestore(&host->lock, flags); |
897 | } | 910 | } |
898 | 911 | ||
@@ -1030,6 +1043,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
1030 | 1043 | ||
1031 | result = IRQ_HANDLED; | 1044 | result = IRQ_HANDLED; |
1032 | 1045 | ||
1046 | mmiowb(); | ||
1033 | out: | 1047 | out: |
1034 | spin_unlock(&host->lock); | 1048 | spin_unlock(&host->lock); |
1035 | 1049 | ||
@@ -1095,6 +1109,7 @@ static int sdhci_resume (struct pci_dev *pdev) | |||
1095 | if (chip->hosts[i]->flags & SDHCI_USE_DMA) | 1109 | if (chip->hosts[i]->flags & SDHCI_USE_DMA) |
1096 | pci_set_master(pdev); | 1110 | pci_set_master(pdev); |
1097 | sdhci_init(chip->hosts[i]); | 1111 | sdhci_init(chip->hosts[i]); |
1112 | mmiowb(); | ||
1098 | ret = mmc_resume_host(chip->hosts[i]->mmc); | 1113 | ret = mmc_resume_host(chip->hosts[i]->mmc); |
1099 | if (ret) | 1114 | if (ret) |
1100 | return ret; | 1115 | return ret; |
@@ -1168,6 +1183,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1168 | host = mmc_priv(mmc); | 1183 | host = mmc_priv(mmc); |
1169 | host->mmc = mmc; | 1184 | host->mmc = mmc; |
1170 | 1185 | ||
1186 | host->chip = chip; | ||
1187 | chip->hosts[slot] = host; | ||
1188 | |||
1171 | host->bar = first_bar + slot; | 1189 | host->bar = first_bar + slot; |
1172 | 1190 | ||
1173 | host->addr = pci_resource_start(pdev, host->bar); | 1191 | host->addr = pci_resource_start(pdev, host->bar); |
@@ -1324,8 +1342,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1324 | sdhci_dumpregs(host); | 1342 | sdhci_dumpregs(host); |
1325 | #endif | 1343 | #endif |
1326 | 1344 | ||
1327 | host->chip = chip; | 1345 | mmiowb(); |
1328 | chip->hosts[slot] = host; | ||
1329 | 1346 | ||
1330 | mmc_add_host(mmc); | 1347 | mmc_add_host(mmc); |
1331 | 1348 | ||
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c new file mode 100644 index 00000000000..6d23dc08d16 --- /dev/null +++ b/drivers/mmc/tifm_sd.c | |||
@@ -0,0 +1,933 @@ | |||
1 | /* | ||
2 | * tifm_sd.c - TI FlashMedia driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/tifm.h> | ||
14 | #include <linux/mmc/protocol.h> | ||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/highmem.h> | ||
17 | |||
18 | #define DRIVER_NAME "tifm_sd" | ||
19 | #define DRIVER_VERSION "0.6" | ||
20 | |||
21 | static int no_dma = 0; | ||
22 | static int fixed_timeout = 0; | ||
23 | module_param(no_dma, bool, 0644); | ||
24 | module_param(fixed_timeout, bool, 0644); | ||
25 | |||
26 | /* Constants here are mostly from OMAP5912 datasheet */ | ||
27 | #define TIFM_MMCSD_RESET 0x0002 | ||
28 | #define TIFM_MMCSD_CLKMASK 0x03ff | ||
29 | #define TIFM_MMCSD_POWER 0x0800 | ||
30 | #define TIFM_MMCSD_4BBUS 0x8000 | ||
31 | #define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ | ||
32 | #define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ | ||
33 | #define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ | ||
34 | #define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ | ||
35 | #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ | ||
36 | #define TIFM_MMCSD_READ 0x8000 | ||
37 | |||
38 | #define TIFM_MMCSD_DATAMASK 0x001d /* set bits: EOFB, BRS, CB, EOC */ | ||
39 | #define TIFM_MMCSD_ERRMASK 0x41e0 /* set bits: CERR, CCRC, CTO, DCRC, DTO */ | ||
40 | #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ | ||
41 | #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ | ||
42 | #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ | ||
43 | #define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ | ||
44 | #define TIFM_MMCSD_DTO 0x0020 /* data time-out */ | ||
45 | #define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ | ||
46 | #define TIFM_MMCSD_CTO 0x0080 /* command time-out */ | ||
47 | #define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ | ||
48 | #define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ | ||
49 | #define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ | ||
50 | #define TIFM_MMCSD_CERR 0x4000 /* card status error */ | ||
51 | |||
52 | #define TIFM_MMCSD_FIFO_SIZE 0x0020 | ||
53 | |||
54 | #define TIFM_MMCSD_RSP_R0 0x0000 | ||
55 | #define TIFM_MMCSD_RSP_R1 0x0100 | ||
56 | #define TIFM_MMCSD_RSP_R2 0x0200 | ||
57 | #define TIFM_MMCSD_RSP_R3 0x0300 | ||
58 | #define TIFM_MMCSD_RSP_R4 0x0400 | ||
59 | #define TIFM_MMCSD_RSP_R5 0x0500 | ||
60 | #define TIFM_MMCSD_RSP_R6 0x0600 | ||
61 | |||
62 | #define TIFM_MMCSD_RSP_BUSY 0x0800 | ||
63 | |||
64 | #define TIFM_MMCSD_CMD_BC 0x0000 | ||
65 | #define TIFM_MMCSD_CMD_BCR 0x1000 | ||
66 | #define TIFM_MMCSD_CMD_AC 0x2000 | ||
67 | #define TIFM_MMCSD_CMD_ADTC 0x3000 | ||
68 | |||
69 | typedef enum { | ||
70 | IDLE = 0, | ||
71 | CMD, /* main command ended */ | ||
72 | BRS, /* block transfer finished */ | ||
73 | SCMD, /* stop command ended */ | ||
74 | CARD, /* card left busy state */ | ||
75 | FIFO, /* FIFO operation completed (uncertain) */ | ||
76 | READY | ||
77 | } card_state_t; | ||
78 | |||
79 | enum { | ||
80 | FIFO_RDY = 0x0001, /* hardware dependent value */ | ||
81 | HOST_REG = 0x0002, | ||
82 | EJECT = 0x0004, | ||
83 | EJECT_DONE = 0x0008, | ||
84 | CARD_BUSY = 0x0010, | ||
85 | OPENDRAIN = 0x0040, /* hardware dependent value */ | ||
86 | CARD_EVENT = 0x0100, /* hardware dependent value */ | ||
87 | CARD_RO = 0x0200, /* hardware dependent value */ | ||
88 | FIFO_EVENT = 0x10000 }; /* hardware dependent value */ | ||
89 | |||
90 | struct tifm_sd { | ||
91 | struct tifm_dev *dev; | ||
92 | |||
93 | unsigned int flags; | ||
94 | card_state_t state; | ||
95 | unsigned int clk_freq; | ||
96 | unsigned int clk_div; | ||
97 | unsigned long timeout_jiffies; // software timeout - 2 sec | ||
98 | |||
99 | struct mmc_request *req; | ||
100 | struct work_struct cmd_handler; | ||
101 | struct work_struct abort_handler; | ||
102 | wait_queue_head_t can_eject; | ||
103 | |||
104 | size_t written_blocks; | ||
105 | char *buffer; | ||
106 | size_t buffer_size; | ||
107 | size_t buffer_pos; | ||
108 | |||
109 | }; | ||
110 | |||
111 | static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, | ||
112 | unsigned int host_status) | ||
113 | { | ||
114 | struct mmc_command *cmd = host->req->cmd; | ||
115 | unsigned int t_val = 0, cnt = 0; | ||
116 | |||
117 | if (host_status & TIFM_MMCSD_BRS) { | ||
118 | /* in non-dma rx mode BRS fires when fifo is still not empty */ | ||
119 | if (host->buffer && (cmd->data->flags & MMC_DATA_READ)) { | ||
120 | while (host->buffer_size > host->buffer_pos) { | ||
121 | t_val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
122 | host->buffer[host->buffer_pos++] = t_val & 0xff; | ||
123 | host->buffer[host->buffer_pos++] = | ||
124 | (t_val >> 8) & 0xff; | ||
125 | } | ||
126 | } | ||
127 | return 1; | ||
128 | } else if (host->buffer) { | ||
129 | if ((cmd->data->flags & MMC_DATA_READ) && | ||
130 | (host_status & TIFM_MMCSD_AF)) { | ||
131 | for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { | ||
132 | t_val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
133 | if (host->buffer_size > host->buffer_pos) { | ||
134 | host->buffer[host->buffer_pos++] = | ||
135 | t_val & 0xff; | ||
136 | host->buffer[host->buffer_pos++] = | ||
137 | (t_val >> 8) & 0xff; | ||
138 | } | ||
139 | } | ||
140 | } else if ((cmd->data->flags & MMC_DATA_WRITE) | ||
141 | && (host_status & TIFM_MMCSD_AE)) { | ||
142 | for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { | ||
143 | if (host->buffer_size > host->buffer_pos) { | ||
144 | t_val = host->buffer[host->buffer_pos++] & 0x00ff; | ||
145 | t_val |= ((host->buffer[host->buffer_pos++]) << 8) | ||
146 | & 0xff00; | ||
147 | writel(t_val, | ||
148 | sock->addr + SOCK_MMCSD_DATA); | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) | ||
157 | { | ||
158 | unsigned int rc = 0; | ||
159 | |||
160 | switch (mmc_resp_type(cmd)) { | ||
161 | case MMC_RSP_NONE: | ||
162 | rc |= TIFM_MMCSD_RSP_R0; | ||
163 | break; | ||
164 | case MMC_RSP_R1B: | ||
165 | rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through | ||
166 | case MMC_RSP_R1: | ||
167 | rc |= TIFM_MMCSD_RSP_R1; | ||
168 | break; | ||
169 | case MMC_RSP_R2: | ||
170 | rc |= TIFM_MMCSD_RSP_R2; | ||
171 | break; | ||
172 | case MMC_RSP_R3: | ||
173 | rc |= TIFM_MMCSD_RSP_R3; | ||
174 | break; | ||
175 | case MMC_RSP_R6: | ||
176 | rc |= TIFM_MMCSD_RSP_R6; | ||
177 | break; | ||
178 | default: | ||
179 | BUG(); | ||
180 | } | ||
181 | |||
182 | switch (mmc_cmd_type(cmd)) { | ||
183 | case MMC_CMD_BC: | ||
184 | rc |= TIFM_MMCSD_CMD_BC; | ||
185 | break; | ||
186 | case MMC_CMD_BCR: | ||
187 | rc |= TIFM_MMCSD_CMD_BCR; | ||
188 | break; | ||
189 | case MMC_CMD_AC: | ||
190 | rc |= TIFM_MMCSD_CMD_AC; | ||
191 | break; | ||
192 | case MMC_CMD_ADTC: | ||
193 | rc |= TIFM_MMCSD_CMD_ADTC; | ||
194 | break; | ||
195 | default: | ||
196 | BUG(); | ||
197 | } | ||
198 | return rc; | ||
199 | } | ||
200 | |||
201 | static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) | ||
202 | { | ||
203 | struct tifm_dev *sock = host->dev; | ||
204 | unsigned int cmd_mask = tifm_sd_op_flags(cmd) | | ||
205 | (host->flags & OPENDRAIN); | ||
206 | |||
207 | if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) | ||
208 | cmd_mask |= TIFM_MMCSD_READ; | ||
209 | |||
210 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", | ||
211 | cmd->opcode, cmd->arg, cmd_mask); | ||
212 | |||
213 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); | ||
214 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); | ||
215 | writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); | ||
216 | } | ||
217 | |||
218 | static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) | ||
219 | { | ||
220 | cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) | ||
221 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); | ||
222 | cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) | ||
223 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); | ||
224 | cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) | ||
225 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); | ||
226 | cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) | ||
227 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); | ||
228 | } | ||
229 | |||
230 | static void tifm_sd_process_cmd(struct tifm_dev *sock, struct tifm_sd *host, | ||
231 | unsigned int host_status) | ||
232 | { | ||
233 | struct mmc_command *cmd = host->req->cmd; | ||
234 | |||
235 | change_state: | ||
236 | switch (host->state) { | ||
237 | case IDLE: | ||
238 | return; | ||
239 | case CMD: | ||
240 | if (host_status & TIFM_MMCSD_EOC) { | ||
241 | tifm_sd_fetch_resp(cmd, sock); | ||
242 | if (cmd->data) { | ||
243 | host->state = BRS; | ||
244 | } else | ||
245 | host->state = READY; | ||
246 | goto change_state; | ||
247 | } | ||
248 | break; | ||
249 | case BRS: | ||
250 | if (tifm_sd_transfer_data(sock, host, host_status)) { | ||
251 | if (!host->req->stop) { | ||
252 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
253 | host->state = CARD; | ||
254 | } else { | ||
255 | host->state = | ||
256 | host->buffer ? READY : FIFO; | ||
257 | } | ||
258 | goto change_state; | ||
259 | } | ||
260 | tifm_sd_exec(host, host->req->stop); | ||
261 | host->state = SCMD; | ||
262 | } | ||
263 | break; | ||
264 | case SCMD: | ||
265 | if (host_status & TIFM_MMCSD_EOC) { | ||
266 | tifm_sd_fetch_resp(host->req->stop, sock); | ||
267 | if (cmd->error) { | ||
268 | host->state = READY; | ||
269 | } else if (cmd->data->flags & MMC_DATA_WRITE) { | ||
270 | host->state = CARD; | ||
271 | } else { | ||
272 | host->state = host->buffer ? READY : FIFO; | ||
273 | } | ||
274 | goto change_state; | ||
275 | } | ||
276 | break; | ||
277 | case CARD: | ||
278 | if (!(host->flags & CARD_BUSY) | ||
279 | && (host->written_blocks == cmd->data->blocks)) { | ||
280 | host->state = host->buffer ? READY : FIFO; | ||
281 | goto change_state; | ||
282 | } | ||
283 | break; | ||
284 | case FIFO: | ||
285 | if (host->flags & FIFO_RDY) { | ||
286 | host->state = READY; | ||
287 | host->flags &= ~FIFO_RDY; | ||
288 | goto change_state; | ||
289 | } | ||
290 | break; | ||
291 | case READY: | ||
292 | queue_work(sock->wq, &host->cmd_handler); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | queue_delayed_work(sock->wq, &host->abort_handler, | ||
297 | host->timeout_jiffies); | ||
298 | } | ||
299 | |||
300 | /* Called from interrupt handler */ | ||
301 | static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, | ||
302 | unsigned int sock_irq_status) | ||
303 | { | ||
304 | struct tifm_sd *host; | ||
305 | unsigned int host_status = 0, fifo_status = 0; | ||
306 | int error_code = 0; | ||
307 | |||
308 | spin_lock(&sock->lock); | ||
309 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
310 | cancel_delayed_work(&host->abort_handler); | ||
311 | |||
312 | if (sock_irq_status & FIFO_EVENT) { | ||
313 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); | ||
314 | writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); | ||
315 | |||
316 | host->flags |= fifo_status & FIFO_RDY; | ||
317 | } | ||
318 | |||
319 | if (sock_irq_status & CARD_EVENT) { | ||
320 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
321 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
322 | |||
323 | if (!(host->flags & HOST_REG)) | ||
324 | queue_work(sock->wq, &host->cmd_handler); | ||
325 | if (!host->req) | ||
326 | goto done; | ||
327 | |||
328 | if (host_status & TIFM_MMCSD_ERRMASK) { | ||
329 | if (host_status & TIFM_MMCSD_CERR) | ||
330 | error_code = MMC_ERR_FAILED; | ||
331 | else if (host_status & | ||
332 | (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) | ||
333 | error_code = MMC_ERR_TIMEOUT; | ||
334 | else if (host_status & | ||
335 | (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) | ||
336 | error_code = MMC_ERR_BADCRC; | ||
337 | |||
338 | writel(TIFM_FIFO_INT_SETALL, | ||
339 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
340 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | ||
341 | |||
342 | if (host->req->stop) { | ||
343 | if (host->state == SCMD) { | ||
344 | host->req->stop->error = error_code; | ||
345 | } else if(host->state == BRS) { | ||
346 | host->req->cmd->error = error_code; | ||
347 | tifm_sd_exec(host, host->req->stop); | ||
348 | queue_delayed_work(sock->wq, | ||
349 | &host->abort_handler, | ||
350 | host->timeout_jiffies); | ||
351 | host->state = SCMD; | ||
352 | goto done; | ||
353 | } else { | ||
354 | host->req->cmd->error = error_code; | ||
355 | } | ||
356 | } else { | ||
357 | host->req->cmd->error = error_code; | ||
358 | } | ||
359 | host->state = READY; | ||
360 | } | ||
361 | |||
362 | if (host_status & TIFM_MMCSD_CB) | ||
363 | host->flags |= CARD_BUSY; | ||
364 | if ((host_status & TIFM_MMCSD_EOFB) && | ||
365 | (host->flags & CARD_BUSY)) { | ||
366 | host->written_blocks++; | ||
367 | host->flags &= ~CARD_BUSY; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | if (host->req) | ||
372 | tifm_sd_process_cmd(sock, host, host_status); | ||
373 | done: | ||
374 | dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", | ||
375 | host_status, fifo_status); | ||
376 | spin_unlock(&sock->lock); | ||
377 | return sock_irq_status; | ||
378 | } | ||
379 | |||
380 | static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd) | ||
381 | { | ||
382 | struct tifm_dev *sock = card->dev; | ||
383 | unsigned int dest_cnt; | ||
384 | |||
385 | /* DMA style IO */ | ||
386 | |||
387 | writel(TIFM_FIFO_INT_SETALL, | ||
388 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
389 | writel(long_log2(cmd->data->blksz) - 2, | ||
390 | sock->addr + SOCK_FIFO_PAGE_SIZE); | ||
391 | writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); | ||
392 | writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
393 | |||
394 | dest_cnt = (cmd->data->blocks) << 8; | ||
395 | |||
396 | writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS); | ||
397 | |||
398 | writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
399 | writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
400 | |||
401 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
402 | writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
403 | writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, | ||
404 | sock->addr + SOCK_DMA_CONTROL); | ||
405 | } else { | ||
406 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
407 | writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); | ||
408 | } | ||
409 | } | ||
410 | |||
411 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, | ||
412 | struct mmc_data *data) | ||
413 | { | ||
414 | struct tifm_dev *sock = host->dev; | ||
415 | unsigned int data_timeout = data->timeout_clks; | ||
416 | |||
417 | if (fixed_timeout) | ||
418 | return; | ||
419 | |||
420 | data_timeout += data->timeout_ns / | ||
421 | ((1000000000 / host->clk_freq) * host->clk_div); | ||
422 | data_timeout *= 10; // call it fudge factor for now | ||
423 | |||
424 | if (data_timeout < 0xffff) { | ||
425 | writel((~TIFM_MMCSD_DPE) & | ||
426 | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
427 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
428 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
429 | } else { | ||
430 | writel(TIFM_MMCSD_DPE | | ||
431 | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
432 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
433 | data_timeout = (data_timeout >> 10) + 1; | ||
434 | if(data_timeout > 0xffff) | ||
435 | data_timeout = 0; /* set to unlimited */ | ||
436 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
437 | } | ||
438 | } | ||
439 | |||
440 | static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
441 | { | ||
442 | struct tifm_sd *host = mmc_priv(mmc); | ||
443 | struct tifm_dev *sock = host->dev; | ||
444 | unsigned long flags; | ||
445 | int sg_count = 0; | ||
446 | struct mmc_data *r_data = mrq->cmd->data; | ||
447 | |||
448 | spin_lock_irqsave(&sock->lock, flags); | ||
449 | if (host->flags & EJECT) { | ||
450 | spin_unlock_irqrestore(&sock->lock, flags); | ||
451 | goto err_out; | ||
452 | } | ||
453 | |||
454 | if (host->req) { | ||
455 | printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); | ||
456 | spin_unlock_irqrestore(&sock->lock, flags); | ||
457 | goto err_out; | ||
458 | } | ||
459 | |||
460 | if (r_data) { | ||
461 | tifm_sd_set_data_timeout(host, r_data); | ||
462 | |||
463 | sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len, | ||
464 | mrq->cmd->flags & MMC_DATA_WRITE | ||
465 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
466 | if (sg_count != 1) { | ||
467 | printk(KERN_ERR DRIVER_NAME | ||
468 | ": scatterlist map failed\n"); | ||
469 | spin_unlock_irqrestore(&sock->lock, flags); | ||
470 | goto err_out; | ||
471 | } | ||
472 | |||
473 | host->written_blocks = 0; | ||
474 | host->flags &= ~CARD_BUSY; | ||
475 | tifm_sd_prepare_data(host, mrq->cmd); | ||
476 | } | ||
477 | |||
478 | host->req = mrq; | ||
479 | host->state = CMD; | ||
480 | queue_delayed_work(sock->wq, &host->abort_handler, | ||
481 | host->timeout_jiffies); | ||
482 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
483 | sock->addr + SOCK_CONTROL); | ||
484 | tifm_sd_exec(host, mrq->cmd); | ||
485 | spin_unlock_irqrestore(&sock->lock, flags); | ||
486 | return; | ||
487 | |||
488 | err_out: | ||
489 | if (sg_count > 0) | ||
490 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
491 | (r_data->flags & MMC_DATA_WRITE) | ||
492 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
493 | |||
494 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
495 | mmc_request_done(mmc, mrq); | ||
496 | } | ||
497 | |||
498 | static void tifm_sd_end_cmd(void *data) | ||
499 | { | ||
500 | struct tifm_sd *host = data; | ||
501 | struct tifm_dev *sock = host->dev; | ||
502 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
503 | struct mmc_request *mrq; | ||
504 | struct mmc_data *r_data = 0; | ||
505 | unsigned long flags; | ||
506 | |||
507 | spin_lock_irqsave(&sock->lock, flags); | ||
508 | |||
509 | mrq = host->req; | ||
510 | host->req = 0; | ||
511 | host->state = IDLE; | ||
512 | |||
513 | if (!mrq) { | ||
514 | printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); | ||
515 | spin_unlock_irqrestore(&sock->lock, flags); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | r_data = mrq->cmd->data; | ||
520 | if (r_data) { | ||
521 | if (r_data->flags & MMC_DATA_WRITE) { | ||
522 | r_data->bytes_xfered = host->written_blocks * | ||
523 | r_data->blksz; | ||
524 | } else { | ||
525 | r_data->bytes_xfered = r_data->blocks - | ||
526 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
527 | r_data->bytes_xfered *= r_data->blksz; | ||
528 | r_data->bytes_xfered += r_data->blksz - | ||
529 | readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
530 | } | ||
531 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
532 | (r_data->flags & MMC_DATA_WRITE) | ||
533 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
534 | } | ||
535 | |||
536 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
537 | sock->addr + SOCK_CONTROL); | ||
538 | |||
539 | spin_unlock_irqrestore(&sock->lock, flags); | ||
540 | mmc_request_done(mmc, mrq); | ||
541 | } | ||
542 | |||
543 | static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) | ||
544 | { | ||
545 | struct tifm_sd *host = mmc_priv(mmc); | ||
546 | struct tifm_dev *sock = host->dev; | ||
547 | unsigned long flags; | ||
548 | struct mmc_data *r_data = mrq->cmd->data; | ||
549 | char *t_buffer = 0; | ||
550 | |||
551 | if (r_data) { | ||
552 | t_buffer = kmap(r_data->sg->page); | ||
553 | if (!t_buffer) { | ||
554 | printk(KERN_ERR DRIVER_NAME ": kmap failed\n"); | ||
555 | goto err_out; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | spin_lock_irqsave(&sock->lock, flags); | ||
560 | if (host->flags & EJECT) { | ||
561 | spin_unlock_irqrestore(&sock->lock, flags); | ||
562 | goto err_out; | ||
563 | } | ||
564 | |||
565 | if (host->req) { | ||
566 | printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); | ||
567 | spin_unlock_irqrestore(&sock->lock, flags); | ||
568 | goto err_out; | ||
569 | } | ||
570 | |||
571 | if (r_data) { | ||
572 | tifm_sd_set_data_timeout(host, r_data); | ||
573 | |||
574 | host->buffer = t_buffer + r_data->sg->offset; | ||
575 | host->buffer_size = mrq->cmd->data->blocks * | ||
576 | mrq->cmd->data->blksz; | ||
577 | |||
578 | writel(TIFM_MMCSD_BUFINT | | ||
579 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
580 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
581 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | | ||
582 | (TIFM_MMCSD_FIFO_SIZE - 1), | ||
583 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
584 | |||
585 | host->written_blocks = 0; | ||
586 | host->flags &= ~CARD_BUSY; | ||
587 | host->buffer_pos = 0; | ||
588 | writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
589 | writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
590 | } | ||
591 | |||
592 | host->req = mrq; | ||
593 | host->state = CMD; | ||
594 | queue_delayed_work(sock->wq, &host->abort_handler, | ||
595 | host->timeout_jiffies); | ||
596 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
597 | sock->addr + SOCK_CONTROL); | ||
598 | tifm_sd_exec(host, mrq->cmd); | ||
599 | spin_unlock_irqrestore(&sock->lock, flags); | ||
600 | return; | ||
601 | |||
602 | err_out: | ||
603 | if (t_buffer) | ||
604 | kunmap(r_data->sg->page); | ||
605 | |||
606 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
607 | mmc_request_done(mmc, mrq); | ||
608 | } | ||
609 | |||
610 | static void tifm_sd_end_cmd_nodma(void *data) | ||
611 | { | ||
612 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
613 | struct tifm_dev *sock = host->dev; | ||
614 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
615 | struct mmc_request *mrq; | ||
616 | struct mmc_data *r_data = 0; | ||
617 | unsigned long flags; | ||
618 | |||
619 | spin_lock_irqsave(&sock->lock, flags); | ||
620 | |||
621 | mrq = host->req; | ||
622 | host->req = 0; | ||
623 | host->state = IDLE; | ||
624 | |||
625 | if (!mrq) { | ||
626 | printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); | ||
627 | spin_unlock_irqrestore(&sock->lock, flags); | ||
628 | return; | ||
629 | } | ||
630 | |||
631 | r_data = mrq->cmd->data; | ||
632 | if (r_data) { | ||
633 | writel((~TIFM_MMCSD_BUFINT) & | ||
634 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
635 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
636 | |||
637 | if (r_data->flags & MMC_DATA_WRITE) { | ||
638 | r_data->bytes_xfered = host->written_blocks * | ||
639 | r_data->blksz; | ||
640 | } else { | ||
641 | r_data->bytes_xfered = r_data->blocks - | ||
642 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
643 | r_data->bytes_xfered *= r_data->blksz; | ||
644 | r_data->bytes_xfered += r_data->blksz - | ||
645 | readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
646 | } | ||
647 | host->buffer = 0; | ||
648 | host->buffer_pos = 0; | ||
649 | host->buffer_size = 0; | ||
650 | } | ||
651 | |||
652 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
653 | sock->addr + SOCK_CONTROL); | ||
654 | |||
655 | spin_unlock_irqrestore(&sock->lock, flags); | ||
656 | |||
657 | if (r_data) | ||
658 | kunmap(r_data->sg->page); | ||
659 | |||
660 | mmc_request_done(mmc, mrq); | ||
661 | } | ||
662 | |||
663 | static void tifm_sd_abort(void *data) | ||
664 | { | ||
665 | printk(KERN_ERR DRIVER_NAME | ||
666 | ": card failed to respond for a long period of time"); | ||
667 | tifm_eject(((struct tifm_sd*)data)->dev); | ||
668 | } | ||
669 | |||
670 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
671 | { | ||
672 | struct tifm_sd *host = mmc_priv(mmc); | ||
673 | struct tifm_dev *sock = host->dev; | ||
674 | unsigned int clk_div1, clk_div2; | ||
675 | unsigned long flags; | ||
676 | |||
677 | spin_lock_irqsave(&sock->lock, flags); | ||
678 | |||
679 | dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width, | ||
680 | ios->power_mode); | ||
681 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
682 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
683 | sock->addr + SOCK_MMCSD_CONFIG); | ||
684 | } else { | ||
685 | writel((~TIFM_MMCSD_4BBUS) & | ||
686 | readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
687 | sock->addr + SOCK_MMCSD_CONFIG); | ||
688 | } | ||
689 | |||
690 | if (ios->clock) { | ||
691 | clk_div1 = 20000000 / ios->clock; | ||
692 | if (!clk_div1) | ||
693 | clk_div1 = 1; | ||
694 | |||
695 | clk_div2 = 24000000 / ios->clock; | ||
696 | if (!clk_div2) | ||
697 | clk_div2 = 1; | ||
698 | |||
699 | if ((20000000 / clk_div1) > ios->clock) | ||
700 | clk_div1++; | ||
701 | if ((24000000 / clk_div2) > ios->clock) | ||
702 | clk_div2++; | ||
703 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { | ||
704 | host->clk_freq = 20000000; | ||
705 | host->clk_div = clk_div1; | ||
706 | writel((~TIFM_CTRL_FAST_CLK) & | ||
707 | readl(sock->addr + SOCK_CONTROL), | ||
708 | sock->addr + SOCK_CONTROL); | ||
709 | } else { | ||
710 | host->clk_freq = 24000000; | ||
711 | host->clk_div = clk_div2; | ||
712 | writel(TIFM_CTRL_FAST_CLK | | ||
713 | readl(sock->addr + SOCK_CONTROL), | ||
714 | sock->addr + SOCK_CONTROL); | ||
715 | } | ||
716 | } else { | ||
717 | host->clk_div = 0; | ||
718 | } | ||
719 | host->clk_div &= TIFM_MMCSD_CLKMASK; | ||
720 | writel(host->clk_div | ((~TIFM_MMCSD_CLKMASK) & | ||
721 | readl(sock->addr + SOCK_MMCSD_CONFIG)), | ||
722 | sock->addr + SOCK_MMCSD_CONFIG); | ||
723 | |||
724 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | ||
725 | host->flags |= OPENDRAIN; | ||
726 | else | ||
727 | host->flags &= ~OPENDRAIN; | ||
728 | |||
729 | /* chip_select : maybe later */ | ||
730 | //vdd | ||
731 | //power is set before probe / after remove | ||
732 | //I believe, power_off when already marked for eject is sufficient to | ||
733 | // allow removal. | ||
734 | if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) { | ||
735 | host->flags |= EJECT_DONE; | ||
736 | wake_up_all(&host->can_eject); | ||
737 | } | ||
738 | |||
739 | spin_unlock_irqrestore(&sock->lock, flags); | ||
740 | } | ||
741 | |||
742 | static int tifm_sd_ro(struct mmc_host *mmc) | ||
743 | { | ||
744 | int rc; | ||
745 | struct tifm_sd *host = mmc_priv(mmc); | ||
746 | struct tifm_dev *sock = host->dev; | ||
747 | unsigned long flags; | ||
748 | |||
749 | spin_lock_irqsave(&sock->lock, flags); | ||
750 | |||
751 | host->flags |= (CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)); | ||
752 | rc = (host->flags & CARD_RO) ? 1 : 0; | ||
753 | |||
754 | spin_unlock_irqrestore(&sock->lock, flags); | ||
755 | return rc; | ||
756 | } | ||
757 | |||
758 | static struct mmc_host_ops tifm_sd_ops = { | ||
759 | .request = tifm_sd_request, | ||
760 | .set_ios = tifm_sd_ios, | ||
761 | .get_ro = tifm_sd_ro | ||
762 | }; | ||
763 | |||
764 | static void tifm_sd_register_host(void *data) | ||
765 | { | ||
766 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
767 | struct tifm_dev *sock = host->dev; | ||
768 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
769 | unsigned long flags; | ||
770 | |||
771 | spin_lock_irqsave(&sock->lock, flags); | ||
772 | host->flags |= HOST_REG; | ||
773 | PREPARE_WORK(&host->cmd_handler, | ||
774 | no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, | ||
775 | data); | ||
776 | spin_unlock_irqrestore(&sock->lock, flags); | ||
777 | dev_dbg(&sock->dev, "adding host\n"); | ||
778 | mmc_add_host(mmc); | ||
779 | } | ||
780 | |||
781 | static int tifm_sd_probe(struct tifm_dev *sock) | ||
782 | { | ||
783 | struct mmc_host *mmc; | ||
784 | struct tifm_sd *host; | ||
785 | int rc = -EIO; | ||
786 | |||
787 | if (!(TIFM_SOCK_STATE_OCCUPIED & | ||
788 | readl(sock->addr + SOCK_PRESENT_STATE))) { | ||
789 | printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); | ||
790 | return rc; | ||
791 | } | ||
792 | |||
793 | mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); | ||
794 | if (!mmc) | ||
795 | return -ENOMEM; | ||
796 | |||
797 | host = mmc_priv(mmc); | ||
798 | host->dev = sock; | ||
799 | host->clk_div = 61; | ||
800 | init_waitqueue_head(&host->can_eject); | ||
801 | INIT_WORK(&host->cmd_handler, tifm_sd_register_host, host); | ||
802 | INIT_WORK(&host->abort_handler, tifm_sd_abort, host); | ||
803 | |||
804 | tifm_set_drvdata(sock, mmc); | ||
805 | sock->signal_irq = tifm_sd_signal_irq; | ||
806 | |||
807 | host->clk_freq = 20000000; | ||
808 | host->timeout_jiffies = msecs_to_jiffies(1000); | ||
809 | |||
810 | tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request; | ||
811 | mmc->ops = &tifm_sd_ops; | ||
812 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
813 | mmc->caps = MMC_CAP_4_BIT_DATA; | ||
814 | mmc->f_min = 20000000 / 60; | ||
815 | mmc->f_max = 24000000; | ||
816 | mmc->max_hw_segs = 1; | ||
817 | mmc->max_phys_segs = 1; | ||
818 | mmc->max_sectors = 127; | ||
819 | mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length | ||
820 | |||
821 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
822 | writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); | ||
823 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
824 | sock->addr + SOCK_MMCSD_CONFIG); | ||
825 | |||
826 | for (rc = 0; rc < 50; rc++) { | ||
827 | /* Wait for reset ack */ | ||
828 | if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { | ||
829 | rc = 0; | ||
830 | break; | ||
831 | } | ||
832 | msleep(10); | ||
833 | } | ||
834 | |||
835 | if (rc) { | ||
836 | printk(KERN_ERR DRIVER_NAME | ||
837 | ": card not ready - probe failed\n"); | ||
838 | mmc_free_host(mmc); | ||
839 | return -ENODEV; | ||
840 | } | ||
841 | |||
842 | writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
843 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
844 | sock->addr + SOCK_MMCSD_CONFIG); | ||
845 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
846 | writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK, | ||
847 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
848 | |||
849 | writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); // command timeout 64 clocks for now | ||
850 | writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); | ||
851 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
852 | sock->addr + SOCK_MMCSD_CONFIG); | ||
853 | |||
854 | queue_delayed_work(sock->wq, &host->abort_handler, | ||
855 | host->timeout_jiffies); | ||
856 | |||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static int tifm_sd_host_is_down(struct tifm_dev *sock) | ||
861 | { | ||
862 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
863 | struct tifm_sd *host = mmc_priv(mmc); | ||
864 | unsigned long flags; | ||
865 | int rc = 0; | ||
866 | |||
867 | spin_lock_irqsave(&sock->lock, flags); | ||
868 | rc = (host->flags & EJECT_DONE); | ||
869 | spin_unlock_irqrestore(&sock->lock, flags); | ||
870 | return rc; | ||
871 | } | ||
872 | |||
873 | static void tifm_sd_remove(struct tifm_dev *sock) | ||
874 | { | ||
875 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
876 | struct tifm_sd *host = mmc_priv(mmc); | ||
877 | unsigned long flags; | ||
878 | |||
879 | spin_lock_irqsave(&sock->lock, flags); | ||
880 | host->flags |= EJECT; | ||
881 | if (host->req) | ||
882 | queue_work(sock->wq, &host->cmd_handler); | ||
883 | spin_unlock_irqrestore(&sock->lock, flags); | ||
884 | wait_event_timeout(host->can_eject, tifm_sd_host_is_down(sock), | ||
885 | host->timeout_jiffies); | ||
886 | |||
887 | if (host->flags & HOST_REG) | ||
888 | mmc_remove_host(mmc); | ||
889 | |||
890 | /* The meaning of the bit majority in this constant is unknown. */ | ||
891 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
892 | sock->addr + SOCK_CONTROL); | ||
893 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
894 | writel(TIFM_FIFO_INT_SETALL, | ||
895 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
896 | writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
897 | |||
898 | tifm_set_drvdata(sock, 0); | ||
899 | mmc_free_host(mmc); | ||
900 | } | ||
901 | |||
902 | static tifm_media_id tifm_sd_id_tbl[] = { | ||
903 | FM_SD, 0 | ||
904 | }; | ||
905 | |||
906 | static struct tifm_driver tifm_sd_driver = { | ||
907 | .driver = { | ||
908 | .name = DRIVER_NAME, | ||
909 | .owner = THIS_MODULE | ||
910 | }, | ||
911 | .id_table = tifm_sd_id_tbl, | ||
912 | .probe = tifm_sd_probe, | ||
913 | .remove = tifm_sd_remove | ||
914 | }; | ||
915 | |||
916 | static int __init tifm_sd_init(void) | ||
917 | { | ||
918 | return tifm_register_driver(&tifm_sd_driver); | ||
919 | } | ||
920 | |||
921 | static void __exit tifm_sd_exit(void) | ||
922 | { | ||
923 | tifm_unregister_driver(&tifm_sd_driver); | ||
924 | } | ||
925 | |||
926 | MODULE_AUTHOR("Alex Dubov"); | ||
927 | MODULE_DESCRIPTION("TI FlashMedia SD driver"); | ||
928 | MODULE_LICENSE("GPL"); | ||
929 | MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); | ||
930 | MODULE_VERSION(DRIVER_VERSION); | ||
931 | |||
932 | module_init(tifm_sd_init); | ||
933 | module_exit(tifm_sd_exit); | ||
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 1fbda77cefc..c2949b4367e 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -146,7 +146,7 @@ | |||
146 | #include <asm/superio.h> | 146 | #include <asm/superio.h> |
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | #include <asm/iosapic.h> | 149 | #include <asm/ropes.h> |
150 | #include "./iosapic_private.h" | 150 | #include "./iosapic_private.h" |
151 | 151 | ||
152 | #define MODULE_NAME "iosapic" | 152 | #define MODULE_NAME "iosapic" |
@@ -692,6 +692,7 @@ static void iosapic_end_irq(unsigned int irq) | |||
692 | DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq, | 692 | DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq, |
693 | vi->eoi_addr, vi->eoi_data); | 693 | vi->eoi_addr, vi->eoi_data); |
694 | iosapic_eoi(vi->eoi_addr, vi->eoi_data); | 694 | iosapic_eoi(vi->eoi_addr, vi->eoi_data); |
695 | cpu_end_irq(irq); | ||
695 | } | 696 | } |
696 | 697 | ||
697 | static unsigned int iosapic_startup_irq(unsigned int irq) | 698 | static unsigned int iosapic_startup_irq(unsigned int irq) |
@@ -728,7 +729,7 @@ static struct hw_interrupt_type iosapic_interrupt_type = { | |||
728 | .shutdown = iosapic_disable_irq, | 729 | .shutdown = iosapic_disable_irq, |
729 | .enable = iosapic_enable_irq, | 730 | .enable = iosapic_enable_irq, |
730 | .disable = iosapic_disable_irq, | 731 | .disable = iosapic_disable_irq, |
731 | .ack = no_ack_irq, | 732 | .ack = cpu_ack_irq, |
732 | .end = iosapic_end_irq, | 733 | .end = iosapic_end_irq, |
733 | #ifdef CONFIG_SMP | 734 | #ifdef CONFIG_SMP |
734 | .set_affinity = iosapic_set_affinity_irq, | 735 | .set_affinity = iosapic_set_affinity_irq, |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 3fe4a77fa16..ba6769934c7 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -46,9 +46,9 @@ | |||
46 | #include <asm/page.h> | 46 | #include <asm/page.h> |
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | 48 | ||
49 | #include <asm/ropes.h> | ||
49 | #include <asm/hardware.h> /* for register_parisc_driver() stuff */ | 50 | #include <asm/hardware.h> /* for register_parisc_driver() stuff */ |
50 | #include <asm/parisc-device.h> | 51 | #include <asm/parisc-device.h> |
51 | #include <asm/iosapic.h> /* for iosapic_register() */ | ||
52 | #include <asm/io.h> /* read/write stuff */ | 52 | #include <asm/io.h> /* read/write stuff */ |
53 | 53 | ||
54 | #undef DEBUG_LBA /* general stuff */ | 54 | #undef DEBUG_LBA /* general stuff */ |
@@ -100,113 +100,10 @@ | |||
100 | 100 | ||
101 | #define MODULE_NAME "LBA" | 101 | #define MODULE_NAME "LBA" |
102 | 102 | ||
103 | #define LBA_FUNC_ID 0x0000 /* function id */ | ||
104 | #define LBA_FCLASS 0x0008 /* function class, bist, header, rev... */ | ||
105 | #define LBA_CAPABLE 0x0030 /* capabilities register */ | ||
106 | |||
107 | #define LBA_PCI_CFG_ADDR 0x0040 /* poke CFG address here */ | ||
108 | #define LBA_PCI_CFG_DATA 0x0048 /* read or write data here */ | ||
109 | |||
110 | #define LBA_PMC_MTLT 0x0050 /* Firmware sets this - read only. */ | ||
111 | #define LBA_FW_SCRATCH 0x0058 /* Firmware writes the PCI bus number here. */ | ||
112 | #define LBA_ERROR_ADDR 0x0070 /* On error, address gets logged here */ | ||
113 | |||
114 | #define LBA_ARB_MASK 0x0080 /* bit 0 enable arbitration. PAT/PDC enables */ | ||
115 | #define LBA_ARB_PRI 0x0088 /* firmware sets this. */ | ||
116 | #define LBA_ARB_MODE 0x0090 /* firmware sets this. */ | ||
117 | #define LBA_ARB_MTLT 0x0098 /* firmware sets this. */ | ||
118 | |||
119 | #define LBA_MOD_ID 0x0100 /* Module ID. PDC_PAT_CELL reports 4 */ | ||
120 | |||
121 | #define LBA_STAT_CTL 0x0108 /* Status & Control */ | ||
122 | #define LBA_BUS_RESET 0x01 /* Deassert PCI Bus Reset Signal */ | ||
123 | #define CLEAR_ERRLOG 0x10 /* "Clear Error Log" cmd */ | ||
124 | #define CLEAR_ERRLOG_ENABLE 0x20 /* "Clear Error Log" Enable */ | ||
125 | #define HF_ENABLE 0x40 /* enable HF mode (default is -1 mode) */ | ||
126 | |||
127 | #define LBA_LMMIO_BASE 0x0200 /* < 4GB I/O address range */ | ||
128 | #define LBA_LMMIO_MASK 0x0208 | ||
129 | |||
130 | #define LBA_GMMIO_BASE 0x0210 /* > 4GB I/O address range */ | ||
131 | #define LBA_GMMIO_MASK 0x0218 | ||
132 | |||
133 | #define LBA_WLMMIO_BASE 0x0220 /* All < 4GB ranges under the same *SBA* */ | ||
134 | #define LBA_WLMMIO_MASK 0x0228 | ||
135 | |||
136 | #define LBA_WGMMIO_BASE 0x0230 /* All > 4GB ranges under the same *SBA* */ | ||
137 | #define LBA_WGMMIO_MASK 0x0238 | ||
138 | |||
139 | #define LBA_IOS_BASE 0x0240 /* I/O port space for this LBA */ | ||
140 | #define LBA_IOS_MASK 0x0248 | ||
141 | |||
142 | #define LBA_ELMMIO_BASE 0x0250 /* Extra LMMIO range */ | ||
143 | #define LBA_ELMMIO_MASK 0x0258 | ||
144 | |||
145 | #define LBA_EIOS_BASE 0x0260 /* Extra I/O port space */ | ||
146 | #define LBA_EIOS_MASK 0x0268 | ||
147 | |||
148 | #define LBA_GLOBAL_MASK 0x0270 /* Mercury only: Global Address Mask */ | ||
149 | #define LBA_DMA_CTL 0x0278 /* firmware sets this */ | ||
150 | |||
151 | #define LBA_IBASE 0x0300 /* SBA DMA support */ | ||
152 | #define LBA_IMASK 0x0308 | ||
153 | |||
154 | /* FIXME: ignore DMA Hint stuff until we can measure performance */ | ||
155 | #define LBA_HINT_CFG 0x0310 | ||
156 | #define LBA_HINT_BASE 0x0380 /* 14 registers at every 8 bytes. */ | ||
157 | |||
158 | #define LBA_BUS_MODE 0x0620 | ||
159 | |||
160 | /* ERROR regs are needed for config cycle kluges */ | ||
161 | #define LBA_ERROR_CONFIG 0x0680 | ||
162 | #define LBA_SMART_MODE 0x20 | ||
163 | #define LBA_ERROR_STATUS 0x0688 | ||
164 | #define LBA_ROPE_CTL 0x06A0 | ||
165 | |||
166 | #define LBA_IOSAPIC_BASE 0x800 /* Offset of IRQ logic */ | ||
167 | |||
168 | /* non-postable I/O port space, densely packed */ | 103 | /* non-postable I/O port space, densely packed */ |
169 | #define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL) | 104 | #define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL) |
170 | static void __iomem *astro_iop_base __read_mostly; | 105 | static void __iomem *astro_iop_base __read_mostly; |
171 | 106 | ||
172 | #define ELROY_HVERS 0x782 | ||
173 | #define MERCURY_HVERS 0x783 | ||
174 | #define QUICKSILVER_HVERS 0x784 | ||
175 | |||
176 | static inline int IS_ELROY(struct parisc_device *d) | ||
177 | { | ||
178 | return (d->id.hversion == ELROY_HVERS); | ||
179 | } | ||
180 | |||
181 | static inline int IS_MERCURY(struct parisc_device *d) | ||
182 | { | ||
183 | return (d->id.hversion == MERCURY_HVERS); | ||
184 | } | ||
185 | |||
186 | static inline int IS_QUICKSILVER(struct parisc_device *d) | ||
187 | { | ||
188 | return (d->id.hversion == QUICKSILVER_HVERS); | ||
189 | } | ||
190 | |||
191 | |||
192 | /* | ||
193 | ** lba_device: Per instance Elroy data structure | ||
194 | */ | ||
195 | struct lba_device { | ||
196 | struct pci_hba_data hba; | ||
197 | |||
198 | spinlock_t lba_lock; | ||
199 | void *iosapic_obj; | ||
200 | |||
201 | #ifdef CONFIG_64BIT | ||
202 | void __iomem * iop_base; /* PA_VIEW - for IO port accessor funcs */ | ||
203 | #endif | ||
204 | |||
205 | int flags; /* state/functionality enabled */ | ||
206 | int hw_rev; /* HW revision of chip */ | ||
207 | }; | ||
208 | |||
209 | |||
210 | static u32 lba_t32; | 107 | static u32 lba_t32; |
211 | 108 | ||
212 | /* lba flags */ | 109 | /* lba flags */ |
@@ -1542,8 +1439,8 @@ lba_driver_probe(struct parisc_device *dev) | |||
1542 | default: version = "TR4+"; | 1439 | default: version = "TR4+"; |
1543 | } | 1440 | } |
1544 | 1441 | ||
1545 | printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n", | 1442 | printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n", |
1546 | MODULE_NAME, version, func_class & 0xf, dev->hpa.start); | 1443 | version, func_class & 0xf, dev->hpa.start); |
1547 | 1444 | ||
1548 | if (func_class < 2) { | 1445 | if (func_class < 2) { |
1549 | printk(KERN_WARNING "Can't support LBA older than " | 1446 | printk(KERN_WARNING "Can't support LBA older than " |
@@ -1563,14 +1460,18 @@ lba_driver_probe(struct parisc_device *dev) | |||
1563 | } | 1460 | } |
1564 | 1461 | ||
1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { | 1462 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { |
1463 | int major, minor; | ||
1464 | |||
1566 | func_class &= 0xff; | 1465 | func_class &= 0xff; |
1567 | version = kmalloc(6, GFP_KERNEL); | 1466 | major = func_class >> 4, minor = func_class & 0xf; |
1568 | snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf)); | 1467 | |
1569 | /* We could use one printk for both Elroy and Mercury, | 1468 | /* We could use one printk for both Elroy and Mercury, |
1570 | * but for the mask for func_class. | 1469 | * but for the mask for func_class. |
1571 | */ | 1470 | */ |
1572 | printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n", | 1471 | printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n", |
1573 | MODULE_NAME, version, func_class & 0xff, dev->hpa.start); | 1472 | IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major, |
1473 | minor, func_class, dev->hpa.start); | ||
1474 | |||
1574 | cfg_ops = &mercury_cfg_ops; | 1475 | cfg_ops = &mercury_cfg_ops; |
1575 | } else { | 1476 | } else { |
1576 | printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start); | 1477 | printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start); |
@@ -1600,6 +1501,7 @@ lba_driver_probe(struct parisc_device *dev) | |||
1600 | lba_dev->hba.dev = dev; | 1501 | lba_dev->hba.dev = dev; |
1601 | lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */ | 1502 | lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */ |
1602 | lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */ | 1503 | lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */ |
1504 | parisc_set_drvdata(dev, lba_dev); | ||
1603 | 1505 | ||
1604 | /* ------------ Second : initialize common stuff ---------- */ | 1506 | /* ------------ Second : initialize common stuff ---------- */ |
1605 | pci_bios = &lba_bios_ops; | 1507 | pci_bios = &lba_bios_ops; |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 8b473281551..294c1117098 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -38,22 +38,15 @@ | |||
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/seq_file.h> | 39 | #include <linux/seq_file.h> |
40 | 40 | ||
41 | #include <asm/ropes.h> | ||
42 | #include <asm/mckinley.h> /* for proc_mckinley_root */ | ||
41 | #include <asm/runway.h> /* for proc_runway_root */ | 43 | #include <asm/runway.h> /* for proc_runway_root */ |
42 | #include <asm/pdc.h> /* for PDC_MODEL_* */ | 44 | #include <asm/pdc.h> /* for PDC_MODEL_* */ |
43 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ | 45 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ |
44 | #include <asm/parisc-device.h> | 46 | #include <asm/parisc-device.h> |
45 | 47 | ||
46 | |||
47 | /* declared in arch/parisc/kernel/setup.c */ | ||
48 | extern struct proc_dir_entry * proc_mckinley_root; | ||
49 | |||
50 | #define MODULE_NAME "SBA" | 48 | #define MODULE_NAME "SBA" |
51 | 49 | ||
52 | #ifdef CONFIG_PROC_FS | ||
53 | /* depends on proc fs support. But costs CPU performance */ | ||
54 | #undef SBA_COLLECT_STATS | ||
55 | #endif | ||
56 | |||
57 | /* | 50 | /* |
58 | ** The number of debug flags is a clue - this code is fragile. | 51 | ** The number of debug flags is a clue - this code is fragile. |
59 | ** Don't even think about messing with it unless you have | 52 | ** Don't even think about messing with it unless you have |
@@ -92,202 +85,12 @@ extern struct proc_dir_entry * proc_mckinley_root; | |||
92 | #define DBG_RES(x...) | 85 | #define DBG_RES(x...) |
93 | #endif | 86 | #endif |
94 | 87 | ||
95 | #if defined(CONFIG_64BIT) | ||
96 | /* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */ | ||
97 | #define ZX1_SUPPORT | ||
98 | #endif | ||
99 | |||
100 | #define SBA_INLINE __inline__ | 88 | #define SBA_INLINE __inline__ |
101 | 89 | ||
102 | |||
103 | /* | ||
104 | ** The number of pdir entries to "free" before issueing | ||
105 | ** a read to PCOM register to flush out PCOM writes. | ||
106 | ** Interacts with allocation granularity (ie 4 or 8 entries | ||
107 | ** allocated and free'd/purged at a time might make this | ||
108 | ** less interesting). | ||
109 | */ | ||
110 | #define DELAYED_RESOURCE_CNT 16 | ||
111 | |||
112 | #define DEFAULT_DMA_HINT_REG 0 | 90 | #define DEFAULT_DMA_HINT_REG 0 |
113 | 91 | ||
114 | #define ASTRO_RUNWAY_PORT 0x582 | 92 | struct sba_device *sba_list; |
115 | #define IKE_MERCED_PORT 0x803 | 93 | EXPORT_SYMBOL_GPL(sba_list); |
116 | #define REO_MERCED_PORT 0x804 | ||
117 | #define REOG_MERCED_PORT 0x805 | ||
118 | #define PLUTO_MCKINLEY_PORT 0x880 | ||
119 | |||
120 | #define SBA_FUNC_ID 0x0000 /* function id */ | ||
121 | #define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */ | ||
122 | |||
123 | #define IS_ASTRO(id) ((id)->hversion == ASTRO_RUNWAY_PORT) | ||
124 | #define IS_IKE(id) ((id)->hversion == IKE_MERCED_PORT) | ||
125 | #define IS_PLUTO(id) ((id)->hversion == PLUTO_MCKINLEY_PORT) | ||
126 | |||
127 | #define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */ | ||
128 | |||
129 | #define ASTRO_IOC_OFFSET (32 * SBA_FUNC_SIZE) | ||
130 | #define PLUTO_IOC_OFFSET (1 * SBA_FUNC_SIZE) | ||
131 | /* Ike's IOC's occupy functions 2 and 3 */ | ||
132 | #define IKE_IOC_OFFSET(p) ((p+2) * SBA_FUNC_SIZE) | ||
133 | |||
134 | #define IOC_CTRL 0x8 /* IOC_CTRL offset */ | ||
135 | #define IOC_CTRL_TC (1 << 0) /* TOC Enable */ | ||
136 | #define IOC_CTRL_CE (1 << 1) /* Coalesce Enable */ | ||
137 | #define IOC_CTRL_DE (1 << 2) /* Dillon Enable */ | ||
138 | #define IOC_CTRL_RM (1 << 8) /* Real Mode */ | ||
139 | #define IOC_CTRL_NC (1 << 9) /* Non Coherent Mode */ | ||
140 | #define IOC_CTRL_D4 (1 << 11) /* Disable 4-byte coalescing */ | ||
141 | #define IOC_CTRL_DD (1 << 13) /* Disable distr. LMMIO range coalescing */ | ||
142 | |||
143 | #define MAX_IOC 2 /* per Ike. Pluto/Astro only have 1. */ | ||
144 | |||
145 | #define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */ | ||
146 | |||
147 | |||
148 | /* | ||
149 | ** Offsets into MBIB (Function 0 on Ike and hopefully Astro) | ||
150 | ** Firmware programs this stuff. Don't touch it. | ||
151 | */ | ||
152 | #define LMMIO_DIRECT0_BASE 0x300 | ||
153 | #define LMMIO_DIRECT0_MASK 0x308 | ||
154 | #define LMMIO_DIRECT0_ROUTE 0x310 | ||
155 | |||
156 | #define LMMIO_DIST_BASE 0x360 | ||
157 | #define LMMIO_DIST_MASK 0x368 | ||
158 | #define LMMIO_DIST_ROUTE 0x370 | ||
159 | |||
160 | #define IOS_DIST_BASE 0x390 | ||
161 | #define IOS_DIST_MASK 0x398 | ||
162 | #define IOS_DIST_ROUTE 0x3A0 | ||
163 | |||
164 | #define IOS_DIRECT_BASE 0x3C0 | ||
165 | #define IOS_DIRECT_MASK 0x3C8 | ||
166 | #define IOS_DIRECT_ROUTE 0x3D0 | ||
167 | |||
168 | /* | ||
169 | ** Offsets into I/O TLB (Function 2 and 3 on Ike) | ||
170 | */ | ||
171 | #define ROPE0_CTL 0x200 /* "regbus pci0" */ | ||
172 | #define ROPE1_CTL 0x208 | ||
173 | #define ROPE2_CTL 0x210 | ||
174 | #define ROPE3_CTL 0x218 | ||
175 | #define ROPE4_CTL 0x220 | ||
176 | #define ROPE5_CTL 0x228 | ||
177 | #define ROPE6_CTL 0x230 | ||
178 | #define ROPE7_CTL 0x238 | ||
179 | |||
180 | #define IOC_ROPE0_CFG 0x500 /* pluto only */ | ||
181 | #define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */ | ||
182 | |||
183 | |||
184 | |||
185 | #define HF_ENABLE 0x40 | ||
186 | |||
187 | |||
188 | #define IOC_IBASE 0x300 /* IO TLB */ | ||
189 | #define IOC_IMASK 0x308 | ||
190 | #define IOC_PCOM 0x310 | ||
191 | #define IOC_TCNFG 0x318 | ||
192 | #define IOC_PDIR_BASE 0x320 | ||
193 | |||
194 | /* AGP GART driver looks for this */ | ||
195 | #define SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL | ||
196 | |||
197 | |||
198 | /* | ||
199 | ** IOC supports 4/8/16/64KB page sizes (see TCNFG register) | ||
200 | ** It's safer (avoid memory corruption) to keep DMA page mappings | ||
201 | ** equivalently sized to VM PAGE_SIZE. | ||
202 | ** | ||
203 | ** We really can't avoid generating a new mapping for each | ||
204 | ** page since the Virtual Coherence Index has to be generated | ||
205 | ** and updated for each page. | ||
206 | ** | ||
207 | ** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse. | ||
208 | */ | ||
209 | #define IOVP_SIZE PAGE_SIZE | ||
210 | #define IOVP_SHIFT PAGE_SHIFT | ||
211 | #define IOVP_MASK PAGE_MASK | ||
212 | |||
213 | #define SBA_PERF_CFG 0x708 /* Performance Counter stuff */ | ||
214 | #define SBA_PERF_MASK1 0x718 | ||
215 | #define SBA_PERF_MASK2 0x730 | ||
216 | |||
217 | |||
218 | /* | ||
219 | ** Offsets into PCI Performance Counters (functions 12 and 13) | ||
220 | ** Controlled by PERF registers in function 2 & 3 respectively. | ||
221 | */ | ||
222 | #define SBA_PERF_CNT1 0x200 | ||
223 | #define SBA_PERF_CNT2 0x208 | ||
224 | #define SBA_PERF_CNT3 0x210 | ||
225 | |||
226 | |||
227 | struct ioc { | ||
228 | void __iomem *ioc_hpa; /* I/O MMU base address */ | ||
229 | char *res_map; /* resource map, bit == pdir entry */ | ||
230 | u64 *pdir_base; /* physical base address */ | ||
231 | unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */ | ||
232 | unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */ | ||
233 | #ifdef ZX1_SUPPORT | ||
234 | unsigned long iovp_mask; /* help convert IOVA to IOVP */ | ||
235 | #endif | ||
236 | unsigned long *res_hint; /* next avail IOVP - circular search */ | ||
237 | spinlock_t res_lock; | ||
238 | unsigned int res_bitshift; /* from the LEFT! */ | ||
239 | unsigned int res_size; /* size of resource map in bytes */ | ||
240 | #ifdef SBA_HINT_SUPPORT | ||
241 | /* FIXME : DMA HINTs not used */ | ||
242 | unsigned long hint_mask_pdir; /* bits used for DMA hints */ | ||
243 | unsigned int hint_shift_pdir; | ||
244 | #endif | ||
245 | #if DELAYED_RESOURCE_CNT > 0 | ||
246 | int saved_cnt; | ||
247 | struct sba_dma_pair { | ||
248 | dma_addr_t iova; | ||
249 | size_t size; | ||
250 | } saved[DELAYED_RESOURCE_CNT]; | ||
251 | #endif | ||
252 | |||
253 | #ifdef SBA_COLLECT_STATS | ||
254 | #define SBA_SEARCH_SAMPLE 0x100 | ||
255 | unsigned long avg_search[SBA_SEARCH_SAMPLE]; | ||
256 | unsigned long avg_idx; /* current index into avg_search */ | ||
257 | unsigned long used_pages; | ||
258 | unsigned long msingle_calls; | ||
259 | unsigned long msingle_pages; | ||
260 | unsigned long msg_calls; | ||
261 | unsigned long msg_pages; | ||
262 | unsigned long usingle_calls; | ||
263 | unsigned long usingle_pages; | ||
264 | unsigned long usg_calls; | ||
265 | unsigned long usg_pages; | ||
266 | #endif | ||
267 | |||
268 | /* STUFF We don't need in performance path */ | ||
269 | unsigned int pdir_size; /* in bytes, determined by IOV Space size */ | ||
270 | }; | ||
271 | |||
272 | struct sba_device { | ||
273 | struct sba_device *next; /* list of SBA's in system */ | ||
274 | struct parisc_device *dev; /* dev found in bus walk */ | ||
275 | struct parisc_device_id *iodc; /* data about dev from firmware */ | ||
276 | const char *name; | ||
277 | void __iomem *sba_hpa; /* base address */ | ||
278 | spinlock_t sba_lock; | ||
279 | unsigned int flags; /* state/functionality enabled */ | ||
280 | unsigned int hw_rev; /* HW revision of chip */ | ||
281 | |||
282 | struct resource chip_resv; /* MMIO reserved for chip */ | ||
283 | struct resource iommu_resv; /* MMIO reserved for iommu */ | ||
284 | |||
285 | unsigned int num_ioc; /* number of on-board IOC's */ | ||
286 | struct ioc ioc[MAX_IOC]; | ||
287 | }; | ||
288 | |||
289 | |||
290 | static struct sba_device *sba_list; | ||
291 | 94 | ||
292 | static unsigned long ioc_needs_fdc = 0; | 95 | static unsigned long ioc_needs_fdc = 0; |
293 | 96 | ||
@@ -300,8 +103,14 @@ static unsigned long piranha_bad_128k = 0; | |||
300 | /* Looks nice and keeps the compiler happy */ | 103 | /* Looks nice and keeps the compiler happy */ |
301 | #define SBA_DEV(d) ((struct sba_device *) (d)) | 104 | #define SBA_DEV(d) ((struct sba_device *) (d)) |
302 | 105 | ||
106 | #ifdef CONFIG_AGP_PARISC | ||
107 | #define SBA_AGP_SUPPORT | ||
108 | #endif /*CONFIG_AGP_PARISC*/ | ||
109 | |||
303 | #ifdef SBA_AGP_SUPPORT | 110 | #ifdef SBA_AGP_SUPPORT |
304 | static int reserve_sba_gart = 1; | 111 | static int sba_reserve_agpgart = 1; |
112 | module_param(sba_reserve_agpgart, int, 1); | ||
113 | MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); | ||
305 | #endif | 114 | #endif |
306 | 115 | ||
307 | #define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1)) | 116 | #define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1)) |
@@ -741,7 +550,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, | |||
741 | asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); | 550 | asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); |
742 | pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */ | 551 | pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */ |
743 | 552 | ||
744 | pa |= 0x8000000000000000ULL; /* set "valid" bit */ | 553 | pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ |
745 | *pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */ | 554 | *pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */ |
746 | 555 | ||
747 | /* | 556 | /* |
@@ -1498,6 +1307,10 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
1498 | WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); | 1307 | WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); |
1499 | 1308 | ||
1500 | #ifdef SBA_AGP_SUPPORT | 1309 | #ifdef SBA_AGP_SUPPORT |
1310 | { | ||
1311 | struct klist_iter i; | ||
1312 | struct device *dev = NULL; | ||
1313 | |||
1501 | /* | 1314 | /* |
1502 | ** If an AGP device is present, only use half of the IOV space | 1315 | ** If an AGP device is present, only use half of the IOV space |
1503 | ** for PCI DMA. Unfortunately we can't know ahead of time | 1316 | ** for PCI DMA. Unfortunately we can't know ahead of time |
@@ -1506,20 +1319,22 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
1506 | ** We program the next pdir index after we stop w/ a key for | 1319 | ** We program the next pdir index after we stop w/ a key for |
1507 | ** the GART code to handshake on. | 1320 | ** the GART code to handshake on. |
1508 | */ | 1321 | */ |
1509 | device=NULL; | 1322 | klist_iter_init(&sba->dev.klist_children, &i); |
1510 | for (lba = sba->child; lba; lba = lba->sibling) { | 1323 | while (dev = next_device(&i)) { |
1324 | struct parisc_device *lba = to_parisc_device(dev); | ||
1511 | if (IS_QUICKSILVER(lba)) | 1325 | if (IS_QUICKSILVER(lba)) |
1512 | break; | 1326 | agp_found = 1; |
1513 | } | 1327 | } |
1328 | klist_iter_exit(&sba->dev.klist_children, &i); | ||
1514 | 1329 | ||
1515 | if (lba) { | 1330 | if (agp_found && sba_reserve_agpgart) { |
1516 | DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__); | 1331 | printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", |
1332 | __FUNCTION__, (iova_space_size/2) >> 20); | ||
1517 | ioc->pdir_size /= 2; | 1333 | ioc->pdir_size /= 2; |
1518 | ((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE; | 1334 | ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE; |
1519 | } else { | ||
1520 | DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__); | ||
1521 | } | 1335 | } |
1522 | #endif /* 0 */ | 1336 | } |
1337 | #endif /*SBA_AGP_SUPPORT*/ | ||
1523 | 1338 | ||
1524 | } | 1339 | } |
1525 | 1340 | ||
@@ -1701,7 +1516,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1701 | } | 1516 | } |
1702 | #endif | 1517 | #endif |
1703 | 1518 | ||
1704 | if (!IS_PLUTO(sba_dev->iodc)) { | 1519 | if (!IS_PLUTO(sba_dev->dev)) { |
1705 | ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL); | 1520 | ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL); |
1706 | DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->", | 1521 | DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->", |
1707 | __FUNCTION__, sba_dev->sba_hpa, ioc_ctl); | 1522 | __FUNCTION__, sba_dev->sba_hpa, ioc_ctl); |
@@ -1718,9 +1533,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1718 | #endif | 1533 | #endif |
1719 | } /* if !PLUTO */ | 1534 | } /* if !PLUTO */ |
1720 | 1535 | ||
1721 | if (IS_ASTRO(sba_dev->iodc)) { | 1536 | if (IS_ASTRO(sba_dev->dev)) { |
1722 | int err; | 1537 | int err; |
1723 | /* PAT_PDC (L-class) also reports the same goofy base */ | ||
1724 | sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET); | 1538 | sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET); |
1725 | num_ioc = 1; | 1539 | num_ioc = 1; |
1726 | 1540 | ||
@@ -1730,13 +1544,9 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1730 | err = request_resource(&iomem_resource, &(sba_dev->chip_resv)); | 1544 | err = request_resource(&iomem_resource, &(sba_dev->chip_resv)); |
1731 | BUG_ON(err < 0); | 1545 | BUG_ON(err < 0); |
1732 | 1546 | ||
1733 | } else if (IS_PLUTO(sba_dev->iodc)) { | 1547 | } else if (IS_PLUTO(sba_dev->dev)) { |
1734 | int err; | 1548 | int err; |
1735 | 1549 | ||
1736 | /* We use a negative value for IOC HPA so it gets | ||
1737 | * corrected when we add it with IKE's IOC offset. | ||
1738 | * Doesnt look clean, but fewer code. | ||
1739 | */ | ||
1740 | sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET); | 1550 | sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET); |
1741 | num_ioc = 1; | 1551 | num_ioc = 1; |
1742 | 1552 | ||
@@ -1752,14 +1562,14 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1752 | err = request_resource(&iomem_resource, &(sba_dev->iommu_resv)); | 1562 | err = request_resource(&iomem_resource, &(sba_dev->iommu_resv)); |
1753 | WARN_ON(err < 0); | 1563 | WARN_ON(err < 0); |
1754 | } else { | 1564 | } else { |
1755 | /* IS_IKE (ie N-class, L3000, L1500) */ | 1565 | /* IKE, REO */ |
1756 | sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0)); | 1566 | sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0)); |
1757 | sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1)); | 1567 | sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1)); |
1758 | num_ioc = 2; | 1568 | num_ioc = 2; |
1759 | 1569 | ||
1760 | /* TODO - LOOKUP Ike/Stretch chipset mem map */ | 1570 | /* TODO - LOOKUP Ike/Stretch chipset mem map */ |
1761 | } | 1571 | } |
1762 | /* XXX: What about Reo? */ | 1572 | /* XXX: What about Reo Grande? */ |
1763 | 1573 | ||
1764 | sba_dev->num_ioc = num_ioc; | 1574 | sba_dev->num_ioc = num_ioc; |
1765 | for (i = 0; i < num_ioc; i++) { | 1575 | for (i = 0; i < num_ioc; i++) { |
@@ -1774,7 +1584,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1774 | * Overrides bit 1 in DMA Hint Sets. | 1584 | * Overrides bit 1 in DMA Hint Sets. |
1775 | * Improves netperf UDP_STREAM by ~10% for bcm5701. | 1585 | * Improves netperf UDP_STREAM by ~10% for bcm5701. |
1776 | */ | 1586 | */ |
1777 | if (IS_PLUTO(sba_dev->iodc)) { | 1587 | if (IS_PLUTO(sba_dev->dev)) { |
1778 | void __iomem *rope_cfg; | 1588 | void __iomem *rope_cfg; |
1779 | unsigned long cfg_val; | 1589 | unsigned long cfg_val; |
1780 | 1590 | ||
@@ -1803,7 +1613,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1803 | READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400) | 1613 | READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400) |
1804 | ); | 1614 | ); |
1805 | 1615 | ||
1806 | if (IS_PLUTO(sba_dev->iodc)) { | 1616 | if (IS_PLUTO(sba_dev->dev)) { |
1807 | sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i); | 1617 | sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i); |
1808 | } else { | 1618 | } else { |
1809 | sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i); | 1619 | sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i); |
@@ -2067,7 +1877,7 @@ sba_driver_callback(struct parisc_device *dev) | |||
2067 | /* Read HW Rev First */ | 1877 | /* Read HW Rev First */ |
2068 | func_class = READ_REG(sba_addr + SBA_FCLASS); | 1878 | func_class = READ_REG(sba_addr + SBA_FCLASS); |
2069 | 1879 | ||
2070 | if (IS_ASTRO(&dev->id)) { | 1880 | if (IS_ASTRO(dev)) { |
2071 | unsigned long fclass; | 1881 | unsigned long fclass; |
2072 | static char astro_rev[]="Astro ?.?"; | 1882 | static char astro_rev[]="Astro ?.?"; |
2073 | 1883 | ||
@@ -2078,11 +1888,11 @@ sba_driver_callback(struct parisc_device *dev) | |||
2078 | astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3); | 1888 | astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3); |
2079 | version = astro_rev; | 1889 | version = astro_rev; |
2080 | 1890 | ||
2081 | } else if (IS_IKE(&dev->id)) { | 1891 | } else if (IS_IKE(dev)) { |
2082 | static char ike_rev[] = "Ike rev ?"; | 1892 | static char ike_rev[] = "Ike rev ?"; |
2083 | ike_rev[8] = '0' + (char) (func_class & 0xff); | 1893 | ike_rev[8] = '0' + (char) (func_class & 0xff); |
2084 | version = ike_rev; | 1894 | version = ike_rev; |
2085 | } else if (IS_PLUTO(&dev->id)) { | 1895 | } else if (IS_PLUTO(dev)) { |
2086 | static char pluto_rev[]="Pluto ?.?"; | 1896 | static char pluto_rev[]="Pluto ?.?"; |
2087 | pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4); | 1897 | pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4); |
2088 | pluto_rev[8] = '0' + (char) (func_class & 0x0f); | 1898 | pluto_rev[8] = '0' + (char) (func_class & 0x0f); |
@@ -2097,7 +1907,7 @@ sba_driver_callback(struct parisc_device *dev) | |||
2097 | global_ioc_cnt = count_parisc_driver(&sba_driver); | 1907 | global_ioc_cnt = count_parisc_driver(&sba_driver); |
2098 | 1908 | ||
2099 | /* Astro and Pluto have one IOC per SBA */ | 1909 | /* Astro and Pluto have one IOC per SBA */ |
2100 | if ((!IS_ASTRO(&dev->id)) || (!IS_PLUTO(&dev->id))) | 1910 | if ((!IS_ASTRO(dev)) || (!IS_PLUTO(dev))) |
2101 | global_ioc_cnt *= 2; | 1911 | global_ioc_cnt *= 2; |
2102 | } | 1912 | } |
2103 | 1913 | ||
@@ -2117,7 +1927,6 @@ sba_driver_callback(struct parisc_device *dev) | |||
2117 | 1927 | ||
2118 | sba_dev->dev = dev; | 1928 | sba_dev->dev = dev; |
2119 | sba_dev->hw_rev = func_class; | 1929 | sba_dev->hw_rev = func_class; |
2120 | sba_dev->iodc = &dev->id; | ||
2121 | sba_dev->name = dev->name; | 1930 | sba_dev->name = dev->name; |
2122 | sba_dev->sba_hpa = sba_addr; | 1931 | sba_dev->sba_hpa = sba_addr; |
2123 | 1932 | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index c27e782e6df..30294127a0a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -52,3 +52,11 @@ config PCI_DEBUG | |||
52 | 52 | ||
53 | When in doubt, say N. | 53 | When in doubt, say N. |
54 | 54 | ||
55 | config HT_IRQ | ||
56 | bool "Interrupts on hypertransport devices" | ||
57 | default y | ||
58 | depends on X86_LOCAL_APIC && X86_IO_APIC | ||
59 | help | ||
60 | This allows native hypertransport devices to use interrupts. | ||
61 | |||
62 | If unsure say Y. | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index f2d152b818f..e3beb784406 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -14,6 +14,12 @@ obj-$(CONFIG_HOTPLUG) += hotplug.o | |||
14 | # Build the PCI Hotplug drivers if we were asked to | 14 | # Build the PCI Hotplug drivers if we were asked to |
15 | obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ | 15 | obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ |
16 | 16 | ||
17 | # Build the PCI MSI interrupt support | ||
18 | obj-$(CONFIG_PCI_MSI) += msi.o | ||
19 | |||
20 | # Build the Hypertransport interrupt support | ||
21 | obj-$(CONFIG_HT_IRQ) += htirq.o | ||
22 | |||
17 | # | 23 | # |
18 | # Some architectures use the generic PCI setup functions | 24 | # Some architectures use the generic PCI setup functions |
19 | # | 25 | # |
@@ -27,11 +33,6 @@ obj-$(CONFIG_PPC64) += setup-bus.o | |||
27 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | 33 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o |
28 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 34 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
29 | 35 | ||
30 | msiobj-y := msi.o msi-apic.o | ||
31 | msiobj-$(CONFIG_IA64_GENERIC) += msi-altix.o | ||
32 | msiobj-$(CONFIG_IA64_SGI_SN2) += msi-altix.o | ||
33 | obj-$(CONFIG_PCI_MSI) += $(msiobj-y) | ||
34 | |||
35 | # | 36 | # |
36 | # ACPI Related PCI FW Functions | 37 | # ACPI Related PCI FW Functions |
37 | # | 38 | # |
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c new file mode 100644 index 00000000000..0e27f2404a8 --- /dev/null +++ b/drivers/pci/htirq.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | * File: htirq.c | ||
3 | * Purpose: Hypertransport Interrupt Capability | ||
4 | * | ||
5 | * Copyright (C) 2006 Linux Networx | ||
6 | * Copyright (C) Eric Biederman <ebiederman@lnxi.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/irq.h> | ||
10 | #include <linux/pci.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/gfp.h> | ||
14 | #include <linux/htirq.h> | ||
15 | |||
16 | /* Global ht irq lock. | ||
17 | * | ||
18 | * This is needed to serialize access to the data port in hypertransport | ||
19 | * irq capability. | ||
20 | * | ||
21 | * With multiple simultaneous hypertransport irq devices it might pay | ||
22 | * to make this more fine grained. But start with simple, stupid, and correct. | ||
23 | */ | ||
24 | static DEFINE_SPINLOCK(ht_irq_lock); | ||
25 | |||
26 | struct ht_irq_cfg { | ||
27 | struct pci_dev *dev; | ||
28 | unsigned pos; | ||
29 | unsigned idx; | ||
30 | }; | ||
31 | |||
32 | void write_ht_irq_low(unsigned int irq, u32 data) | ||
33 | { | ||
34 | struct ht_irq_cfg *cfg = get_irq_data(irq); | ||
35 | unsigned long flags; | ||
36 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
37 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | ||
38 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
39 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
40 | } | ||
41 | |||
42 | void write_ht_irq_high(unsigned int irq, u32 data) | ||
43 | { | ||
44 | struct ht_irq_cfg *cfg = get_irq_data(irq); | ||
45 | unsigned long flags; | ||
46 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
47 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); | ||
48 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
49 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
50 | } | ||
51 | |||
52 | u32 read_ht_irq_low(unsigned int irq) | ||
53 | { | ||
54 | struct ht_irq_cfg *cfg = get_irq_data(irq); | ||
55 | unsigned long flags; | ||
56 | u32 data; | ||
57 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
58 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | ||
59 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | ||
60 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
61 | return data; | ||
62 | } | ||
63 | |||
64 | u32 read_ht_irq_high(unsigned int irq) | ||
65 | { | ||
66 | struct ht_irq_cfg *cfg = get_irq_data(irq); | ||
67 | unsigned long flags; | ||
68 | u32 data; | ||
69 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
70 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); | ||
71 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | ||
72 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
73 | return data; | ||
74 | } | ||
75 | |||
76 | void mask_ht_irq(unsigned int irq) | ||
77 | { | ||
78 | struct ht_irq_cfg *cfg; | ||
79 | unsigned long flags; | ||
80 | u32 data; | ||
81 | |||
82 | cfg = get_irq_data(irq); | ||
83 | |||
84 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
85 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | ||
86 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | ||
87 | data |= 1; | ||
88 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
89 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
90 | } | ||
91 | |||
92 | void unmask_ht_irq(unsigned int irq) | ||
93 | { | ||
94 | struct ht_irq_cfg *cfg; | ||
95 | unsigned long flags; | ||
96 | u32 data; | ||
97 | |||
98 | cfg = get_irq_data(irq); | ||
99 | |||
100 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
101 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | ||
102 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | ||
103 | data &= ~1; | ||
104 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
105 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * ht_create_irq - create an irq and attach it to a device. | ||
110 | * @dev: The hypertransport device to find the irq capability on. | ||
111 | * @idx: Which of the possible irqs to attach to. | ||
112 | * | ||
113 | * ht_create_irq is needs to be called for all hypertransport devices | ||
114 | * that generate irqs. | ||
115 | * | ||
116 | * The irq number of the new irq or a negative error value is returned. | ||
117 | */ | ||
118 | int ht_create_irq(struct pci_dev *dev, int idx) | ||
119 | { | ||
120 | struct ht_irq_cfg *cfg; | ||
121 | unsigned long flags; | ||
122 | u32 data; | ||
123 | int max_irq; | ||
124 | int pos; | ||
125 | int irq; | ||
126 | |||
127 | pos = pci_find_capability(dev, PCI_CAP_ID_HT); | ||
128 | while (pos) { | ||
129 | u8 subtype; | ||
130 | pci_read_config_byte(dev, pos + 3, &subtype); | ||
131 | if (subtype == HT_CAPTYPE_IRQ) | ||
132 | break; | ||
133 | pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT); | ||
134 | } | ||
135 | if (!pos) | ||
136 | return -EINVAL; | ||
137 | |||
138 | /* Verify the idx I want to use is in range */ | ||
139 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
140 | pci_write_config_byte(dev, pos + 2, 1); | ||
141 | pci_read_config_dword(dev, pos + 4, &data); | ||
142 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
143 | |||
144 | max_irq = (data >> 16) & 0xff; | ||
145 | if ( idx > max_irq) | ||
146 | return -EINVAL; | ||
147 | |||
148 | cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); | ||
149 | if (!cfg) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | cfg->dev = dev; | ||
153 | cfg->pos = pos; | ||
154 | cfg->idx = 0x10 + (idx * 2); | ||
155 | |||
156 | irq = create_irq(); | ||
157 | if (irq < 0) { | ||
158 | kfree(cfg); | ||
159 | return -EBUSY; | ||
160 | } | ||
161 | set_irq_data(irq, cfg); | ||
162 | |||
163 | if (arch_setup_ht_irq(irq, dev) < 0) { | ||
164 | ht_destroy_irq(irq); | ||
165 | return -EBUSY; | ||
166 | } | ||
167 | |||
168 | return irq; | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * ht_destroy_irq - destroy an irq created with ht_create_irq | ||
173 | * | ||
174 | * This reverses ht_create_irq removing the specified irq from | ||
175 | * existence. The irq should be free before this happens. | ||
176 | */ | ||
177 | void ht_destroy_irq(unsigned int irq) | ||
178 | { | ||
179 | struct ht_irq_cfg *cfg; | ||
180 | |||
181 | cfg = get_irq_data(irq); | ||
182 | set_irq_chip(irq, NULL); | ||
183 | set_irq_data(irq, NULL); | ||
184 | destroy_irq(irq); | ||
185 | |||
186 | kfree(cfg); | ||
187 | } | ||
188 | |||
189 | EXPORT_SYMBOL(ht_create_irq); | ||
190 | EXPORT_SYMBOL(ht_destroy_irq); | ||
diff --git a/drivers/pci/msi-altix.c b/drivers/pci/msi-altix.c deleted file mode 100644 index bed4183a5e3..00000000000 --- a/drivers/pci/msi-altix.c +++ /dev/null | |||
@@ -1,210 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/pci.h> | ||
11 | #include <linux/cpumask.h> | ||
12 | |||
13 | #include <asm/sn/addrs.h> | ||
14 | #include <asm/sn/intr.h> | ||
15 | #include <asm/sn/pcibus_provider_defs.h> | ||
16 | #include <asm/sn/pcidev.h> | ||
17 | #include <asm/sn/nodepda.h> | ||
18 | |||
19 | #include "msi.h" | ||
20 | |||
21 | struct sn_msi_info { | ||
22 | u64 pci_addr; | ||
23 | struct sn_irq_info *sn_irq_info; | ||
24 | }; | ||
25 | |||
26 | static struct sn_msi_info *sn_msi_info; | ||
27 | |||
28 | static void | ||
29 | sn_msi_teardown(unsigned int vector) | ||
30 | { | ||
31 | nasid_t nasid; | ||
32 | int widget; | ||
33 | struct pci_dev *pdev; | ||
34 | struct pcidev_info *sn_pdev; | ||
35 | struct sn_irq_info *sn_irq_info; | ||
36 | struct pcibus_bussoft *bussoft; | ||
37 | struct sn_pcibus_provider *provider; | ||
38 | |||
39 | sn_irq_info = sn_msi_info[vector].sn_irq_info; | ||
40 | if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) | ||
41 | return; | ||
42 | |||
43 | sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | ||
44 | pdev = sn_pdev->pdi_linux_pcidev; | ||
45 | provider = SN_PCIDEV_BUSPROVIDER(pdev); | ||
46 | |||
47 | (*provider->dma_unmap)(pdev, | ||
48 | sn_msi_info[vector].pci_addr, | ||
49 | PCI_DMA_FROMDEVICE); | ||
50 | sn_msi_info[vector].pci_addr = 0; | ||
51 | |||
52 | bussoft = SN_PCIDEV_BUSSOFT(pdev); | ||
53 | nasid = NASID_GET(bussoft->bs_base); | ||
54 | widget = (nasid & 1) ? | ||
55 | TIO_SWIN_WIDGETNUM(bussoft->bs_base) : | ||
56 | SWIN_WIDGETNUM(bussoft->bs_base); | ||
57 | |||
58 | sn_intr_free(nasid, widget, sn_irq_info); | ||
59 | sn_msi_info[vector].sn_irq_info = NULL; | ||
60 | |||
61 | return; | ||
62 | } | ||
63 | |||
64 | int | ||
65 | sn_msi_setup(struct pci_dev *pdev, unsigned int vector, | ||
66 | u32 *addr_hi, u32 *addr_lo, u32 *data) | ||
67 | { | ||
68 | int widget; | ||
69 | int status; | ||
70 | nasid_t nasid; | ||
71 | u64 bus_addr; | ||
72 | struct sn_irq_info *sn_irq_info; | ||
73 | struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); | ||
74 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); | ||
75 | |||
76 | if (bussoft == NULL) | ||
77 | return -EINVAL; | ||
78 | |||
79 | if (provider == NULL || provider->dma_map_consistent == NULL) | ||
80 | return -EINVAL; | ||
81 | |||
82 | /* | ||
83 | * Set up the vector plumbing. Let the prom (via sn_intr_alloc) | ||
84 | * decide which cpu to direct this msi at by default. | ||
85 | */ | ||
86 | |||
87 | nasid = NASID_GET(bussoft->bs_base); | ||
88 | widget = (nasid & 1) ? | ||
89 | TIO_SWIN_WIDGETNUM(bussoft->bs_base) : | ||
90 | SWIN_WIDGETNUM(bussoft->bs_base); | ||
91 | |||
92 | sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); | ||
93 | if (! sn_irq_info) | ||
94 | return -ENOMEM; | ||
95 | |||
96 | status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1); | ||
97 | if (status) { | ||
98 | kfree(sn_irq_info); | ||
99 | return -ENOMEM; | ||
100 | } | ||
101 | |||
102 | sn_irq_info->irq_int_bit = -1; /* mark this as an MSI irq */ | ||
103 | sn_irq_fixup(pdev, sn_irq_info); | ||
104 | |||
105 | /* Prom probably should fill these in, but doesn't ... */ | ||
106 | sn_irq_info->irq_bridge_type = bussoft->bs_asic_type; | ||
107 | sn_irq_info->irq_bridge = (void *)bussoft->bs_base; | ||
108 | |||
109 | /* | ||
110 | * Map the xio address into bus space | ||
111 | */ | ||
112 | bus_addr = (*provider->dma_map_consistent)(pdev, | ||
113 | sn_irq_info->irq_xtalkaddr, | ||
114 | sizeof(sn_irq_info->irq_xtalkaddr), | ||
115 | SN_DMA_MSI|SN_DMA_ADDR_XIO); | ||
116 | if (! bus_addr) { | ||
117 | sn_intr_free(nasid, widget, sn_irq_info); | ||
118 | kfree(sn_irq_info); | ||
119 | return -ENOMEM; | ||
120 | } | ||
121 | |||
122 | sn_msi_info[vector].sn_irq_info = sn_irq_info; | ||
123 | sn_msi_info[vector].pci_addr = bus_addr; | ||
124 | |||
125 | *addr_hi = (u32)(bus_addr >> 32); | ||
126 | *addr_lo = (u32)(bus_addr & 0x00000000ffffffff); | ||
127 | |||
128 | /* | ||
129 | * In the SN platform, bit 16 is a "send vector" bit which | ||
130 | * must be present in order to move the vector through the system. | ||
131 | */ | ||
132 | *data = 0x100 + (unsigned int)vector; | ||
133 | |||
134 | #ifdef CONFIG_SMP | ||
135 | set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0); | ||
136 | #endif | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static void | ||
142 | sn_msi_target(unsigned int vector, unsigned int cpu, | ||
143 | u32 *addr_hi, u32 *addr_lo) | ||
144 | { | ||
145 | int slice; | ||
146 | nasid_t nasid; | ||
147 | u64 bus_addr; | ||
148 | struct pci_dev *pdev; | ||
149 | struct pcidev_info *sn_pdev; | ||
150 | struct sn_irq_info *sn_irq_info; | ||
151 | struct sn_irq_info *new_irq_info; | ||
152 | struct sn_pcibus_provider *provider; | ||
153 | |||
154 | sn_irq_info = sn_msi_info[vector].sn_irq_info; | ||
155 | if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) | ||
156 | return; | ||
157 | |||
158 | /* | ||
159 | * Release XIO resources for the old MSI PCI address | ||
160 | */ | ||
161 | |||
162 | sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | ||
163 | pdev = sn_pdev->pdi_linux_pcidev; | ||
164 | provider = SN_PCIDEV_BUSPROVIDER(pdev); | ||
165 | |||
166 | bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo); | ||
167 | (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE); | ||
168 | sn_msi_info[vector].pci_addr = 0; | ||
169 | |||
170 | nasid = cpuid_to_nasid(cpu); | ||
171 | slice = cpuid_to_slice(cpu); | ||
172 | |||
173 | new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice); | ||
174 | sn_msi_info[vector].sn_irq_info = new_irq_info; | ||
175 | if (new_irq_info == NULL) | ||
176 | return; | ||
177 | |||
178 | /* | ||
179 | * Map the xio address into bus space | ||
180 | */ | ||
181 | |||
182 | bus_addr = (*provider->dma_map_consistent)(pdev, | ||
183 | new_irq_info->irq_xtalkaddr, | ||
184 | sizeof(new_irq_info->irq_xtalkaddr), | ||
185 | SN_DMA_MSI|SN_DMA_ADDR_XIO); | ||
186 | |||
187 | sn_msi_info[vector].pci_addr = bus_addr; | ||
188 | *addr_hi = (u32)(bus_addr >> 32); | ||
189 | *addr_lo = (u32)(bus_addr & 0x00000000ffffffff); | ||
190 | } | ||
191 | |||
192 | struct msi_ops sn_msi_ops = { | ||
193 | .setup = sn_msi_setup, | ||
194 | .teardown = sn_msi_teardown, | ||
195 | #ifdef CONFIG_SMP | ||
196 | .target = sn_msi_target, | ||
197 | #endif | ||
198 | }; | ||
199 | |||
200 | int | ||
201 | sn_msi_init(void) | ||
202 | { | ||
203 | sn_msi_info = | ||
204 | kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL); | ||
205 | if (! sn_msi_info) | ||
206 | return -ENOMEM; | ||
207 | |||
208 | msi_register(&sn_msi_ops); | ||
209 | return 0; | ||
210 | } | ||
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c deleted file mode 100644 index 5ed798b319c..00000000000 --- a/drivers/pci/msi-apic.c +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /* | ||
2 | * MSI hooks for standard x86 apic | ||
3 | */ | ||
4 | |||
5 | #include <linux/pci.h> | ||
6 | #include <linux/irq.h> | ||
7 | #include <asm/smp.h> | ||
8 | |||
9 | #include "msi.h" | ||
10 | |||
11 | /* | ||
12 | * Shifts for APIC-based data | ||
13 | */ | ||
14 | |||
15 | #define MSI_DATA_VECTOR_SHIFT 0 | ||
16 | #define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) | ||
17 | |||
18 | #define MSI_DATA_DELIVERY_SHIFT 8 | ||
19 | #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) | ||
20 | #define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT) | ||
21 | |||
22 | #define MSI_DATA_LEVEL_SHIFT 14 | ||
23 | #define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT) | ||
24 | #define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT) | ||
25 | |||
26 | #define MSI_DATA_TRIGGER_SHIFT 15 | ||
27 | #define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT) | ||
28 | #define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT) | ||
29 | |||
30 | /* | ||
31 | * Shift/mask fields for APIC-based bus address | ||
32 | */ | ||
33 | |||
34 | #define MSI_ADDR_HEADER 0xfee00000 | ||
35 | |||
36 | #define MSI_ADDR_DESTID_MASK 0xfff0000f | ||
37 | #define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT) | ||
38 | |||
39 | #define MSI_ADDR_DESTMODE_SHIFT 2 | ||
40 | #define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT) | ||
41 | #define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT) | ||
42 | |||
43 | #define MSI_ADDR_REDIRECTION_SHIFT 3 | ||
44 | #define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) | ||
45 | #define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) | ||
46 | |||
47 | |||
48 | static void | ||
49 | msi_target_apic(unsigned int vector, | ||
50 | unsigned int dest_cpu, | ||
51 | u32 *address_hi, /* in/out */ | ||
52 | u32 *address_lo) /* in/out */ | ||
53 | { | ||
54 | u32 addr = *address_lo; | ||
55 | |||
56 | addr &= MSI_ADDR_DESTID_MASK; | ||
57 | addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu)); | ||
58 | |||
59 | *address_lo = addr; | ||
60 | } | ||
61 | |||
62 | static int | ||
63 | msi_setup_apic(struct pci_dev *pdev, /* unused in generic */ | ||
64 | unsigned int vector, | ||
65 | u32 *address_hi, | ||
66 | u32 *address_lo, | ||
67 | u32 *data) | ||
68 | { | ||
69 | unsigned long dest_phys_id; | ||
70 | |||
71 | dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); | ||
72 | |||
73 | *address_hi = 0; | ||
74 | *address_lo = MSI_ADDR_HEADER | | ||
75 | MSI_ADDR_DESTMODE_PHYS | | ||
76 | MSI_ADDR_REDIRECTION_CPU | | ||
77 | MSI_ADDR_DESTID_CPU(dest_phys_id); | ||
78 | |||
79 | *data = MSI_DATA_TRIGGER_EDGE | | ||
80 | MSI_DATA_LEVEL_ASSERT | | ||
81 | MSI_DATA_DELIVERY_FIXED | | ||
82 | MSI_DATA_VECTOR(vector); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static void | ||
88 | msi_teardown_apic(unsigned int vector) | ||
89 | { | ||
90 | return; /* no-op */ | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Generic ops used on most IA archs/platforms. Set with msi_register() | ||
95 | */ | ||
96 | |||
97 | struct msi_ops msi_apic_ops = { | ||
98 | .setup = msi_setup_apic, | ||
99 | .teardown = msi_teardown_apic, | ||
100 | .target = msi_target_apic, | ||
101 | }; | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 27a057409ec..f9fdc54473c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | 6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/err.h> | ||
9 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
10 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
11 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
@@ -14,6 +15,7 @@ | |||
14 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
15 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
16 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/msi.h> | ||
17 | 19 | ||
18 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
19 | #include <asm/io.h> | 21 | #include <asm/io.h> |
@@ -27,23 +29,6 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; | |||
27 | static kmem_cache_t* msi_cachep; | 29 | static kmem_cache_t* msi_cachep; |
28 | 30 | ||
29 | static int pci_msi_enable = 1; | 31 | static int pci_msi_enable = 1; |
30 | static int last_alloc_vector; | ||
31 | static int nr_released_vectors; | ||
32 | static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; | ||
33 | static int nr_msix_devices; | ||
34 | |||
35 | #ifndef CONFIG_X86_IO_APIC | ||
36 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; | ||
37 | #endif | ||
38 | |||
39 | static struct msi_ops *msi_ops; | ||
40 | |||
41 | int | ||
42 | msi_register(struct msi_ops *ops) | ||
43 | { | ||
44 | msi_ops = ops; | ||
45 | return 0; | ||
46 | } | ||
47 | 32 | ||
48 | static int msi_cache_init(void) | 33 | static int msi_cache_init(void) |
49 | { | 34 | { |
@@ -55,26 +40,25 @@ static int msi_cache_init(void) | |||
55 | return 0; | 40 | return 0; |
56 | } | 41 | } |
57 | 42 | ||
58 | static void msi_set_mask_bit(unsigned int vector, int flag) | 43 | static void msi_set_mask_bit(unsigned int irq, int flag) |
59 | { | 44 | { |
60 | struct msi_desc *entry; | 45 | struct msi_desc *entry; |
61 | 46 | ||
62 | entry = (struct msi_desc *)msi_desc[vector]; | 47 | entry = msi_desc[irq]; |
63 | if (!entry || !entry->dev || !entry->mask_base) | 48 | BUG_ON(!entry || !entry->dev); |
64 | return; | ||
65 | switch (entry->msi_attrib.type) { | 49 | switch (entry->msi_attrib.type) { |
66 | case PCI_CAP_ID_MSI: | 50 | case PCI_CAP_ID_MSI: |
67 | { | 51 | if (entry->msi_attrib.maskbit) { |
68 | int pos; | 52 | int pos; |
69 | u32 mask_bits; | 53 | u32 mask_bits; |
70 | 54 | ||
71 | pos = (long)entry->mask_base; | 55 | pos = (long)entry->mask_base; |
72 | pci_read_config_dword(entry->dev, pos, &mask_bits); | 56 | pci_read_config_dword(entry->dev, pos, &mask_bits); |
73 | mask_bits &= ~(1); | 57 | mask_bits &= ~(1); |
74 | mask_bits |= flag; | 58 | mask_bits |= flag; |
75 | pci_write_config_dword(entry->dev, pos, mask_bits); | 59 | pci_write_config_dword(entry->dev, pos, mask_bits); |
60 | } | ||
76 | break; | 61 | break; |
77 | } | ||
78 | case PCI_CAP_ID_MSIX: | 62 | case PCI_CAP_ID_MSIX: |
79 | { | 63 | { |
80 | int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | 64 | int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + |
@@ -83,261 +67,101 @@ static void msi_set_mask_bit(unsigned int vector, int flag) | |||
83 | break; | 67 | break; |
84 | } | 68 | } |
85 | default: | 69 | default: |
70 | BUG(); | ||
86 | break; | 71 | break; |
87 | } | 72 | } |
88 | } | 73 | } |
89 | 74 | ||
90 | #ifdef CONFIG_SMP | 75 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) |
91 | static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) | ||
92 | { | 76 | { |
93 | struct msi_desc *entry; | 77 | struct msi_desc *entry = get_irq_data(irq); |
94 | u32 address_hi, address_lo; | 78 | switch(entry->msi_attrib.type) { |
95 | unsigned int irq = vector; | ||
96 | unsigned int dest_cpu = first_cpu(cpu_mask); | ||
97 | |||
98 | entry = (struct msi_desc *)msi_desc[vector]; | ||
99 | if (!entry || !entry->dev) | ||
100 | return; | ||
101 | |||
102 | switch (entry->msi_attrib.type) { | ||
103 | case PCI_CAP_ID_MSI: | 79 | case PCI_CAP_ID_MSI: |
104 | { | 80 | { |
105 | int pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI); | 81 | struct pci_dev *dev = entry->dev; |
106 | 82 | int pos = entry->msi_attrib.pos; | |
107 | if (!pos) | 83 | u16 data; |
108 | return; | 84 | |
109 | 85 | pci_read_config_dword(dev, msi_lower_address_reg(pos), | |
110 | pci_read_config_dword(entry->dev, msi_upper_address_reg(pos), | 86 | &msg->address_lo); |
111 | &address_hi); | 87 | if (entry->msi_attrib.is_64) { |
112 | pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), | 88 | pci_read_config_dword(dev, msi_upper_address_reg(pos), |
113 | &address_lo); | 89 | &msg->address_hi); |
114 | 90 | pci_read_config_word(dev, msi_data_reg(pos, 1), &data); | |
115 | msi_ops->target(vector, dest_cpu, &address_hi, &address_lo); | 91 | } else { |
116 | 92 | msg->address_hi = 0; | |
117 | pci_write_config_dword(entry->dev, msi_upper_address_reg(pos), | 93 | pci_read_config_word(dev, msi_data_reg(pos, 1), &data); |
118 | address_hi); | 94 | } |
119 | pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), | 95 | msg->data = data; |
120 | address_lo); | ||
121 | set_native_irq_info(irq, cpu_mask); | ||
122 | break; | 96 | break; |
123 | } | 97 | } |
124 | case PCI_CAP_ID_MSIX: | 98 | case PCI_CAP_ID_MSIX: |
125 | { | 99 | { |
126 | int offset_hi = | 100 | void __iomem *base; |
127 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | 101 | base = entry->mask_base + |
128 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET; | 102 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; |
129 | int offset_lo = | ||
130 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
131 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; | ||
132 | |||
133 | address_hi = readl(entry->mask_base + offset_hi); | ||
134 | address_lo = readl(entry->mask_base + offset_lo); | ||
135 | 103 | ||
136 | msi_ops->target(vector, dest_cpu, &address_hi, &address_lo); | 104 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); |
105 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
106 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET); | ||
107 | break; | ||
108 | } | ||
109 | default: | ||
110 | BUG(); | ||
111 | } | ||
112 | } | ||
137 | 113 | ||
138 | writel(address_hi, entry->mask_base + offset_hi); | 114 | void write_msi_msg(unsigned int irq, struct msi_msg *msg) |
139 | writel(address_lo, entry->mask_base + offset_lo); | 115 | { |
140 | set_native_irq_info(irq, cpu_mask); | 116 | struct msi_desc *entry = get_irq_data(irq); |
117 | switch (entry->msi_attrib.type) { | ||
118 | case PCI_CAP_ID_MSI: | ||
119 | { | ||
120 | struct pci_dev *dev = entry->dev; | ||
121 | int pos = entry->msi_attrib.pos; | ||
122 | |||
123 | pci_write_config_dword(dev, msi_lower_address_reg(pos), | ||
124 | msg->address_lo); | ||
125 | if (entry->msi_attrib.is_64) { | ||
126 | pci_write_config_dword(dev, msi_upper_address_reg(pos), | ||
127 | msg->address_hi); | ||
128 | pci_write_config_word(dev, msi_data_reg(pos, 1), | ||
129 | msg->data); | ||
130 | } else { | ||
131 | pci_write_config_word(dev, msi_data_reg(pos, 0), | ||
132 | msg->data); | ||
133 | } | ||
141 | break; | 134 | break; |
142 | } | 135 | } |
143 | default: | 136 | case PCI_CAP_ID_MSIX: |
137 | { | ||
138 | void __iomem *base; | ||
139 | base = entry->mask_base + | ||
140 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | ||
141 | |||
142 | writel(msg->address_lo, | ||
143 | base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | ||
144 | writel(msg->address_hi, | ||
145 | base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
146 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET); | ||
144 | break; | 147 | break; |
145 | } | 148 | } |
146 | } | 149 | default: |
147 | #else | 150 | BUG(); |
148 | #define set_msi_affinity NULL | ||
149 | #endif /* CONFIG_SMP */ | ||
150 | |||
151 | static void mask_MSI_irq(unsigned int vector) | ||
152 | { | ||
153 | msi_set_mask_bit(vector, 1); | ||
154 | } | ||
155 | |||
156 | static void unmask_MSI_irq(unsigned int vector) | ||
157 | { | ||
158 | msi_set_mask_bit(vector, 0); | ||
159 | } | ||
160 | |||
161 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) | ||
162 | { | ||
163 | struct msi_desc *entry; | ||
164 | unsigned long flags; | ||
165 | |||
166 | spin_lock_irqsave(&msi_lock, flags); | ||
167 | entry = msi_desc[vector]; | ||
168 | if (!entry || !entry->dev) { | ||
169 | spin_unlock_irqrestore(&msi_lock, flags); | ||
170 | return 0; | ||
171 | } | 151 | } |
172 | entry->msi_attrib.state = 1; /* Mark it active */ | ||
173 | spin_unlock_irqrestore(&msi_lock, flags); | ||
174 | |||
175 | return 0; /* never anything pending */ | ||
176 | } | 152 | } |
177 | 153 | ||
178 | static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) | 154 | void mask_msi_irq(unsigned int irq) |
179 | { | 155 | { |
180 | startup_msi_irq_wo_maskbit(vector); | 156 | msi_set_mask_bit(irq, 1); |
181 | unmask_MSI_irq(vector); | ||
182 | return 0; /* never anything pending */ | ||
183 | } | ||
184 | |||
185 | static void shutdown_msi_irq(unsigned int vector) | ||
186 | { | ||
187 | struct msi_desc *entry; | ||
188 | unsigned long flags; | ||
189 | |||
190 | spin_lock_irqsave(&msi_lock, flags); | ||
191 | entry = msi_desc[vector]; | ||
192 | if (entry && entry->dev) | ||
193 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
194 | spin_unlock_irqrestore(&msi_lock, flags); | ||
195 | } | 157 | } |
196 | 158 | ||
197 | static void end_msi_irq_wo_maskbit(unsigned int vector) | 159 | void unmask_msi_irq(unsigned int irq) |
198 | { | 160 | { |
199 | move_native_irq(vector); | 161 | msi_set_mask_bit(irq, 0); |
200 | ack_APIC_irq(); | ||
201 | } | ||
202 | |||
203 | static void end_msi_irq_w_maskbit(unsigned int vector) | ||
204 | { | ||
205 | move_native_irq(vector); | ||
206 | unmask_MSI_irq(vector); | ||
207 | ack_APIC_irq(); | ||
208 | } | ||
209 | |||
210 | static void do_nothing(unsigned int vector) | ||
211 | { | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices, | ||
216 | * which implement the MSI-X Capability Structure. | ||
217 | */ | ||
218 | static struct hw_interrupt_type msix_irq_type = { | ||
219 | .typename = "PCI-MSI-X", | ||
220 | .startup = startup_msi_irq_w_maskbit, | ||
221 | .shutdown = shutdown_msi_irq, | ||
222 | .enable = unmask_MSI_irq, | ||
223 | .disable = mask_MSI_irq, | ||
224 | .ack = mask_MSI_irq, | ||
225 | .end = end_msi_irq_w_maskbit, | ||
226 | .set_affinity = set_msi_affinity | ||
227 | }; | ||
228 | |||
229 | /* | ||
230 | * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices, | ||
231 | * which implement the MSI Capability Structure with | ||
232 | * Mask-and-Pending Bits. | ||
233 | */ | ||
234 | static struct hw_interrupt_type msi_irq_w_maskbit_type = { | ||
235 | .typename = "PCI-MSI", | ||
236 | .startup = startup_msi_irq_w_maskbit, | ||
237 | .shutdown = shutdown_msi_irq, | ||
238 | .enable = unmask_MSI_irq, | ||
239 | .disable = mask_MSI_irq, | ||
240 | .ack = mask_MSI_irq, | ||
241 | .end = end_msi_irq_w_maskbit, | ||
242 | .set_affinity = set_msi_affinity | ||
243 | }; | ||
244 | |||
245 | /* | ||
246 | * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices, | ||
247 | * which implement the MSI Capability Structure without | ||
248 | * Mask-and-Pending Bits. | ||
249 | */ | ||
250 | static struct hw_interrupt_type msi_irq_wo_maskbit_type = { | ||
251 | .typename = "PCI-MSI", | ||
252 | .startup = startup_msi_irq_wo_maskbit, | ||
253 | .shutdown = shutdown_msi_irq, | ||
254 | .enable = do_nothing, | ||
255 | .disable = do_nothing, | ||
256 | .ack = do_nothing, | ||
257 | .end = end_msi_irq_wo_maskbit, | ||
258 | .set_affinity = set_msi_affinity | ||
259 | }; | ||
260 | |||
261 | static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); | ||
262 | static int assign_msi_vector(void) | ||
263 | { | ||
264 | static int new_vector_avail = 1; | ||
265 | int vector; | ||
266 | unsigned long flags; | ||
267 | |||
268 | /* | ||
269 | * msi_lock is provided to ensure that successful allocation of MSI | ||
270 | * vector is assigned unique among drivers. | ||
271 | */ | ||
272 | spin_lock_irqsave(&msi_lock, flags); | ||
273 | |||
274 | if (!new_vector_avail) { | ||
275 | int free_vector = 0; | ||
276 | |||
277 | /* | ||
278 | * vector_irq[] = -1 indicates that this specific vector is: | ||
279 | * - assigned for MSI (since MSI have no associated IRQ) or | ||
280 | * - assigned for legacy if less than 16, or | ||
281 | * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping | ||
282 | * vector_irq[] = 0 indicates that this vector, previously | ||
283 | * assigned for MSI, is freed by hotplug removed operations. | ||
284 | * This vector will be reused for any subsequent hotplug added | ||
285 | * operations. | ||
286 | * vector_irq[] > 0 indicates that this vector is assigned for | ||
287 | * IOxAPIC IRQs. This vector and its value provides a 1-to-1 | ||
288 | * vector-to-IOxAPIC IRQ mapping. | ||
289 | */ | ||
290 | for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { | ||
291 | if (vector_irq[vector] != 0) | ||
292 | continue; | ||
293 | free_vector = vector; | ||
294 | if (!msi_desc[vector]) | ||
295 | break; | ||
296 | else | ||
297 | continue; | ||
298 | } | ||
299 | if (!free_vector) { | ||
300 | spin_unlock_irqrestore(&msi_lock, flags); | ||
301 | return -EBUSY; | ||
302 | } | ||
303 | vector_irq[free_vector] = -1; | ||
304 | nr_released_vectors--; | ||
305 | spin_unlock_irqrestore(&msi_lock, flags); | ||
306 | if (msi_desc[free_vector] != NULL) { | ||
307 | struct pci_dev *dev; | ||
308 | int tail; | ||
309 | |||
310 | /* free all linked vectors before re-assign */ | ||
311 | do { | ||
312 | spin_lock_irqsave(&msi_lock, flags); | ||
313 | dev = msi_desc[free_vector]->dev; | ||
314 | tail = msi_desc[free_vector]->link.tail; | ||
315 | spin_unlock_irqrestore(&msi_lock, flags); | ||
316 | msi_free_vector(dev, tail, 1); | ||
317 | } while (free_vector != tail); | ||
318 | } | ||
319 | |||
320 | return free_vector; | ||
321 | } | ||
322 | vector = assign_irq_vector(AUTO_ASSIGN); | ||
323 | last_alloc_vector = vector; | ||
324 | if (vector == LAST_DEVICE_VECTOR) | ||
325 | new_vector_avail = 0; | ||
326 | |||
327 | spin_unlock_irqrestore(&msi_lock, flags); | ||
328 | return vector; | ||
329 | } | ||
330 | |||
331 | static int get_new_vector(void) | ||
332 | { | ||
333 | int vector = assign_msi_vector(); | ||
334 | |||
335 | if (vector > 0) | ||
336 | set_intr_gate(vector, interrupt[vector]); | ||
337 | |||
338 | return vector; | ||
339 | } | 162 | } |
340 | 163 | ||
164 | static int msi_free_irq(struct pci_dev* dev, int irq); | ||
341 | static int msi_init(void) | 165 | static int msi_init(void) |
342 | { | 166 | { |
343 | static int status = -ENOMEM; | 167 | static int status = -ENOMEM; |
@@ -352,22 +176,6 @@ static int msi_init(void) | |||
352 | return status; | 176 | return status; |
353 | } | 177 | } |
354 | 178 | ||
355 | status = msi_arch_init(); | ||
356 | if (status < 0) { | ||
357 | pci_msi_enable = 0; | ||
358 | printk(KERN_WARNING | ||
359 | "PCI: MSI arch init failed. MSI disabled.\n"); | ||
360 | return status; | ||
361 | } | ||
362 | |||
363 | if (! msi_ops) { | ||
364 | printk(KERN_WARNING | ||
365 | "PCI: MSI ops not registered. MSI disabled.\n"); | ||
366 | status = -EINVAL; | ||
367 | return status; | ||
368 | } | ||
369 | |||
370 | last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); | ||
371 | status = msi_cache_init(); | 179 | status = msi_cache_init(); |
372 | if (status < 0) { | 180 | if (status < 0) { |
373 | pci_msi_enable = 0; | 181 | pci_msi_enable = 0; |
@@ -375,23 +183,9 @@ static int msi_init(void) | |||
375 | return status; | 183 | return status; |
376 | } | 184 | } |
377 | 185 | ||
378 | if (last_alloc_vector < 0) { | ||
379 | pci_msi_enable = 0; | ||
380 | printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); | ||
381 | status = -EBUSY; | ||
382 | return status; | ||
383 | } | ||
384 | vector_irq[last_alloc_vector] = 0; | ||
385 | nr_released_vectors++; | ||
386 | |||
387 | return status; | 186 | return status; |
388 | } | 187 | } |
389 | 188 | ||
390 | static int get_msi_vector(struct pci_dev *dev) | ||
391 | { | ||
392 | return get_new_vector(); | ||
393 | } | ||
394 | |||
395 | static struct msi_desc* alloc_msi_entry(void) | 189 | static struct msi_desc* alloc_msi_entry(void) |
396 | { | 190 | { |
397 | struct msi_desc *entry; | 191 | struct msi_desc *entry; |
@@ -406,29 +200,44 @@ static struct msi_desc* alloc_msi_entry(void) | |||
406 | return entry; | 200 | return entry; |
407 | } | 201 | } |
408 | 202 | ||
409 | static void attach_msi_entry(struct msi_desc *entry, int vector) | 203 | static void attach_msi_entry(struct msi_desc *entry, int irq) |
410 | { | 204 | { |
411 | unsigned long flags; | 205 | unsigned long flags; |
412 | 206 | ||
413 | spin_lock_irqsave(&msi_lock, flags); | 207 | spin_lock_irqsave(&msi_lock, flags); |
414 | msi_desc[vector] = entry; | 208 | msi_desc[irq] = entry; |
415 | spin_unlock_irqrestore(&msi_lock, flags); | 209 | spin_unlock_irqrestore(&msi_lock, flags); |
416 | } | 210 | } |
417 | 211 | ||
418 | static void irq_handler_init(int cap_id, int pos, int mask) | 212 | static int create_msi_irq(void) |
419 | { | 213 | { |
420 | unsigned long flags; | 214 | struct msi_desc *entry; |
215 | int irq; | ||
421 | 216 | ||
422 | spin_lock_irqsave(&irq_desc[pos].lock, flags); | 217 | entry = alloc_msi_entry(); |
423 | if (cap_id == PCI_CAP_ID_MSIX) | 218 | if (!entry) |
424 | irq_desc[pos].chip = &msix_irq_type; | 219 | return -ENOMEM; |
425 | else { | 220 | |
426 | if (!mask) | 221 | irq = create_irq(); |
427 | irq_desc[pos].chip = &msi_irq_wo_maskbit_type; | 222 | if (irq < 0) { |
428 | else | 223 | kmem_cache_free(msi_cachep, entry); |
429 | irq_desc[pos].chip = &msi_irq_w_maskbit_type; | 224 | return -EBUSY; |
430 | } | 225 | } |
431 | spin_unlock_irqrestore(&irq_desc[pos].lock, flags); | 226 | |
227 | set_irq_data(irq, entry); | ||
228 | |||
229 | return irq; | ||
230 | } | ||
231 | |||
232 | static void destroy_msi_irq(unsigned int irq) | ||
233 | { | ||
234 | struct msi_desc *entry; | ||
235 | |||
236 | entry = get_irq_data(irq); | ||
237 | set_irq_chip(irq, NULL); | ||
238 | set_irq_data(irq, NULL); | ||
239 | destroy_irq(irq); | ||
240 | kmem_cache_free(msi_cachep, entry); | ||
432 | } | 241 | } |
433 | 242 | ||
434 | static void enable_msi_mode(struct pci_dev *dev, int pos, int type) | 243 | static void enable_msi_mode(struct pci_dev *dev, int pos, int type) |
@@ -473,21 +282,21 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type) | |||
473 | } | 282 | } |
474 | } | 283 | } |
475 | 284 | ||
476 | static int msi_lookup_vector(struct pci_dev *dev, int type) | 285 | static int msi_lookup_irq(struct pci_dev *dev, int type) |
477 | { | 286 | { |
478 | int vector; | 287 | int irq; |
479 | unsigned long flags; | 288 | unsigned long flags; |
480 | 289 | ||
481 | spin_lock_irqsave(&msi_lock, flags); | 290 | spin_lock_irqsave(&msi_lock, flags); |
482 | for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { | 291 | for (irq = 0; irq < NR_IRQS; irq++) { |
483 | if (!msi_desc[vector] || msi_desc[vector]->dev != dev || | 292 | if (!msi_desc[irq] || msi_desc[irq]->dev != dev || |
484 | msi_desc[vector]->msi_attrib.type != type || | 293 | msi_desc[irq]->msi_attrib.type != type || |
485 | msi_desc[vector]->msi_attrib.default_vector != dev->irq) | 294 | msi_desc[irq]->msi_attrib.default_irq != dev->irq) |
486 | continue; | 295 | continue; |
487 | spin_unlock_irqrestore(&msi_lock, flags); | 296 | spin_unlock_irqrestore(&msi_lock, flags); |
488 | /* This pre-assigned MSI vector for this device | 297 | /* This pre-assigned MSI irq for this device |
489 | already exits. Override dev->irq with this vector */ | 298 | already exits. Override dev->irq with this irq */ |
490 | dev->irq = vector; | 299 | dev->irq = irq; |
491 | return 0; | 300 | return 0; |
492 | } | 301 | } |
493 | spin_unlock_irqrestore(&msi_lock, flags); | 302 | spin_unlock_irqrestore(&msi_lock, flags); |
@@ -499,11 +308,6 @@ void pci_scan_msi_device(struct pci_dev *dev) | |||
499 | { | 308 | { |
500 | if (!dev) | 309 | if (!dev) |
501 | return; | 310 | return; |
502 | |||
503 | if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0) | ||
504 | nr_msix_devices++; | ||
505 | else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0) | ||
506 | nr_reserved_vectors++; | ||
507 | } | 311 | } |
508 | 312 | ||
509 | #ifdef CONFIG_PM | 313 | #ifdef CONFIG_PM |
@@ -577,7 +381,7 @@ int pci_save_msix_state(struct pci_dev *dev) | |||
577 | { | 381 | { |
578 | int pos; | 382 | int pos; |
579 | int temp; | 383 | int temp; |
580 | int vector, head, tail = 0; | 384 | int irq, head, tail = 0; |
581 | u16 control; | 385 | u16 control; |
582 | struct pci_cap_saved_state *save_state; | 386 | struct pci_cap_saved_state *save_state; |
583 | 387 | ||
@@ -599,33 +403,20 @@ int pci_save_msix_state(struct pci_dev *dev) | |||
599 | 403 | ||
600 | /* save the table */ | 404 | /* save the table */ |
601 | temp = dev->irq; | 405 | temp = dev->irq; |
602 | if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 406 | if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
603 | kfree(save_state); | 407 | kfree(save_state); |
604 | return -EINVAL; | 408 | return -EINVAL; |
605 | } | 409 | } |
606 | 410 | ||
607 | vector = head = dev->irq; | 411 | irq = head = dev->irq; |
608 | while (head != tail) { | 412 | while (head != tail) { |
609 | int j; | ||
610 | void __iomem *base; | ||
611 | struct msi_desc *entry; | 413 | struct msi_desc *entry; |
612 | 414 | ||
613 | entry = msi_desc[vector]; | 415 | entry = msi_desc[irq]; |
614 | base = entry->mask_base; | 416 | read_msi_msg(irq, &entry->msg_save); |
615 | j = entry->msi_attrib.entry_nr; | 417 | |
616 | 418 | tail = msi_desc[irq]->link.tail; | |
617 | entry->address_lo_save = | 419 | irq = tail; |
618 | readl(base + j * PCI_MSIX_ENTRY_SIZE + | ||
619 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | ||
620 | entry->address_hi_save = | ||
621 | readl(base + j * PCI_MSIX_ENTRY_SIZE + | ||
622 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
623 | entry->data_save = | ||
624 | readl(base + j * PCI_MSIX_ENTRY_SIZE + | ||
625 | PCI_MSIX_ENTRY_DATA_OFFSET); | ||
626 | |||
627 | tail = msi_desc[vector]->link.tail; | ||
628 | vector = tail; | ||
629 | } | 420 | } |
630 | dev->irq = temp; | 421 | dev->irq = temp; |
631 | 422 | ||
@@ -638,9 +429,7 @@ void pci_restore_msix_state(struct pci_dev *dev) | |||
638 | { | 429 | { |
639 | u16 save; | 430 | u16 save; |
640 | int pos; | 431 | int pos; |
641 | int vector, head, tail = 0; | 432 | int irq, head, tail = 0; |
642 | void __iomem *base; | ||
643 | int j; | ||
644 | struct msi_desc *entry; | 433 | struct msi_desc *entry; |
645 | int temp; | 434 | int temp; |
646 | struct pci_cap_saved_state *save_state; | 435 | struct pci_cap_saved_state *save_state; |
@@ -658,26 +447,15 @@ void pci_restore_msix_state(struct pci_dev *dev) | |||
658 | 447 | ||
659 | /* route the table */ | 448 | /* route the table */ |
660 | temp = dev->irq; | 449 | temp = dev->irq; |
661 | if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) | 450 | if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) |
662 | return; | 451 | return; |
663 | vector = head = dev->irq; | 452 | irq = head = dev->irq; |
664 | while (head != tail) { | 453 | while (head != tail) { |
665 | entry = msi_desc[vector]; | 454 | entry = msi_desc[irq]; |
666 | base = entry->mask_base; | 455 | write_msi_msg(irq, &entry->msg_save); |
667 | j = entry->msi_attrib.entry_nr; | 456 | |
668 | 457 | tail = msi_desc[irq]->link.tail; | |
669 | writel(entry->address_lo_save, | 458 | irq = tail; |
670 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
671 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | ||
672 | writel(entry->address_hi_save, | ||
673 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
674 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
675 | writel(entry->data_save, | ||
676 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
677 | PCI_MSIX_ENTRY_DATA_OFFSET); | ||
678 | |||
679 | tail = msi_desc[vector]->link.tail; | ||
680 | vector = tail; | ||
681 | } | 459 | } |
682 | dev->irq = temp; | 460 | dev->irq = temp; |
683 | 461 | ||
@@ -686,104 +464,68 @@ void pci_restore_msix_state(struct pci_dev *dev) | |||
686 | } | 464 | } |
687 | #endif | 465 | #endif |
688 | 466 | ||
689 | static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry) | ||
690 | { | ||
691 | int status; | ||
692 | u32 address_hi; | ||
693 | u32 address_lo; | ||
694 | u32 data; | ||
695 | int pos, vector = dev->irq; | ||
696 | u16 control; | ||
697 | |||
698 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
699 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
700 | |||
701 | /* Configure MSI capability structure */ | ||
702 | status = msi_ops->setup(dev, vector, &address_hi, &address_lo, &data); | ||
703 | if (status < 0) | ||
704 | return status; | ||
705 | |||
706 | pci_write_config_dword(dev, msi_lower_address_reg(pos), address_lo); | ||
707 | if (is_64bit_address(control)) { | ||
708 | pci_write_config_dword(dev, | ||
709 | msi_upper_address_reg(pos), address_hi); | ||
710 | pci_write_config_word(dev, | ||
711 | msi_data_reg(pos, 1), data); | ||
712 | } else | ||
713 | pci_write_config_word(dev, | ||
714 | msi_data_reg(pos, 0), data); | ||
715 | if (entry->msi_attrib.maskbit) { | ||
716 | unsigned int maskbits, temp; | ||
717 | /* All MSIs are unmasked by default, Mask them all */ | ||
718 | pci_read_config_dword(dev, | ||
719 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
720 | &maskbits); | ||
721 | temp = (1 << multi_msi_capable(control)); | ||
722 | temp = ((temp - 1) & ~temp); | ||
723 | maskbits |= temp; | ||
724 | pci_write_config_dword(dev, | ||
725 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
726 | maskbits); | ||
727 | } | ||
728 | |||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | /** | 467 | /** |
733 | * msi_capability_init - configure device's MSI capability structure | 468 | * msi_capability_init - configure device's MSI capability structure |
734 | * @dev: pointer to the pci_dev data structure of MSI device function | 469 | * @dev: pointer to the pci_dev data structure of MSI device function |
735 | * | 470 | * |
736 | * Setup the MSI capability structure of device function with a single | 471 | * Setup the MSI capability structure of device function with a single |
737 | * MSI vector, regardless of device function is capable of handling | 472 | * MSI irq, regardless of device function is capable of handling |
738 | * multiple messages. A return of zero indicates the successful setup | 473 | * multiple messages. A return of zero indicates the successful setup |
739 | * of an entry zero with the new MSI vector or non-zero for otherwise. | 474 | * of an entry zero with the new MSI irq or non-zero for otherwise. |
740 | **/ | 475 | **/ |
741 | static int msi_capability_init(struct pci_dev *dev) | 476 | static int msi_capability_init(struct pci_dev *dev) |
742 | { | 477 | { |
743 | int status; | 478 | int status; |
744 | struct msi_desc *entry; | 479 | struct msi_desc *entry; |
745 | int pos, vector; | 480 | int pos, irq; |
746 | u16 control; | 481 | u16 control; |
747 | 482 | ||
748 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 483 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
749 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 484 | pci_read_config_word(dev, msi_control_reg(pos), &control); |
750 | /* MSI Entry Initialization */ | 485 | /* MSI Entry Initialization */ |
751 | entry = alloc_msi_entry(); | 486 | irq = create_msi_irq(); |
752 | if (!entry) | 487 | if (irq < 0) |
753 | return -ENOMEM; | 488 | return irq; |
754 | 489 | ||
755 | vector = get_msi_vector(dev); | 490 | entry = get_irq_data(irq); |
756 | if (vector < 0) { | 491 | entry->link.head = irq; |
757 | kmem_cache_free(msi_cachep, entry); | 492 | entry->link.tail = irq; |
758 | return -EBUSY; | ||
759 | } | ||
760 | entry->link.head = vector; | ||
761 | entry->link.tail = vector; | ||
762 | entry->msi_attrib.type = PCI_CAP_ID_MSI; | 493 | entry->msi_attrib.type = PCI_CAP_ID_MSI; |
763 | entry->msi_attrib.state = 0; /* Mark it not active */ | 494 | entry->msi_attrib.is_64 = is_64bit_address(control); |
764 | entry->msi_attrib.entry_nr = 0; | 495 | entry->msi_attrib.entry_nr = 0; |
765 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 496 | entry->msi_attrib.maskbit = is_mask_bit_support(control); |
766 | entry->msi_attrib.default_vector = dev->irq; /* Save IOAPIC IRQ */ | 497 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
767 | dev->irq = vector; | 498 | entry->msi_attrib.pos = pos; |
768 | entry->dev = dev; | ||
769 | if (is_mask_bit_support(control)) { | 499 | if (is_mask_bit_support(control)) { |
770 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, | 500 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, |
771 | is_64bit_address(control)); | 501 | is_64bit_address(control)); |
772 | } | 502 | } |
773 | /* Replace with MSI handler */ | 503 | entry->dev = dev; |
774 | irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); | 504 | if (entry->msi_attrib.maskbit) { |
505 | unsigned int maskbits, temp; | ||
506 | /* All MSIs are unmasked by default, Mask them all */ | ||
507 | pci_read_config_dword(dev, | ||
508 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
509 | &maskbits); | ||
510 | temp = (1 << multi_msi_capable(control)); | ||
511 | temp = ((temp - 1) & ~temp); | ||
512 | maskbits |= temp; | ||
513 | pci_write_config_dword(dev, | ||
514 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
515 | maskbits); | ||
516 | } | ||
775 | /* Configure MSI capability structure */ | 517 | /* Configure MSI capability structure */ |
776 | status = msi_register_init(dev, entry); | 518 | status = arch_setup_msi_irq(irq, dev); |
777 | if (status != 0) { | 519 | if (status < 0) { |
778 | dev->irq = entry->msi_attrib.default_vector; | 520 | destroy_msi_irq(irq); |
779 | kmem_cache_free(msi_cachep, entry); | ||
780 | return status; | 521 | return status; |
781 | } | 522 | } |
782 | 523 | ||
783 | attach_msi_entry(entry, vector); | 524 | attach_msi_entry(entry, irq); |
784 | /* Set MSI enabled bits */ | 525 | /* Set MSI enabled bits */ |
785 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | 526 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); |
786 | 527 | ||
528 | dev->irq = irq; | ||
787 | return 0; | 529 | return 0; |
788 | } | 530 | } |
789 | 531 | ||
@@ -794,18 +536,15 @@ static int msi_capability_init(struct pci_dev *dev) | |||
794 | * @nvec: number of @entries | 536 | * @nvec: number of @entries |
795 | * | 537 | * |
796 | * Setup the MSI-X capability structure of device function with a | 538 | * Setup the MSI-X capability structure of device function with a |
797 | * single MSI-X vector. A return of zero indicates the successful setup of | 539 | * single MSI-X irq. A return of zero indicates the successful setup of |
798 | * requested MSI-X entries with allocated vectors or non-zero for otherwise. | 540 | * requested MSI-X entries with allocated irqs or non-zero for otherwise. |
799 | **/ | 541 | **/ |
800 | static int msix_capability_init(struct pci_dev *dev, | 542 | static int msix_capability_init(struct pci_dev *dev, |
801 | struct msix_entry *entries, int nvec) | 543 | struct msix_entry *entries, int nvec) |
802 | { | 544 | { |
803 | struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; | 545 | struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; |
804 | u32 address_hi; | ||
805 | u32 address_lo; | ||
806 | u32 data; | ||
807 | int status; | 546 | int status; |
808 | int vector, pos, i, j, nr_entries, temp = 0; | 547 | int irq, pos, i, j, nr_entries, temp = 0; |
809 | unsigned long phys_addr; | 548 | unsigned long phys_addr; |
810 | u32 table_offset; | 549 | u32 table_offset; |
811 | u16 control; | 550 | u16 control; |
@@ -827,65 +566,56 @@ static int msix_capability_init(struct pci_dev *dev, | |||
827 | 566 | ||
828 | /* MSI-X Table Initialization */ | 567 | /* MSI-X Table Initialization */ |
829 | for (i = 0; i < nvec; i++) { | 568 | for (i = 0; i < nvec; i++) { |
830 | entry = alloc_msi_entry(); | 569 | irq = create_msi_irq(); |
831 | if (!entry) | 570 | if (irq < 0) |
832 | break; | 571 | break; |
833 | vector = get_msi_vector(dev); | ||
834 | if (vector < 0) { | ||
835 | kmem_cache_free(msi_cachep, entry); | ||
836 | break; | ||
837 | } | ||
838 | 572 | ||
573 | entry = get_irq_data(irq); | ||
839 | j = entries[i].entry; | 574 | j = entries[i].entry; |
840 | entries[i].vector = vector; | 575 | entries[i].vector = irq; |
841 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; | 576 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; |
842 | entry->msi_attrib.state = 0; /* Mark it not active */ | 577 | entry->msi_attrib.is_64 = 1; |
843 | entry->msi_attrib.entry_nr = j; | 578 | entry->msi_attrib.entry_nr = j; |
844 | entry->msi_attrib.maskbit = 1; | 579 | entry->msi_attrib.maskbit = 1; |
845 | entry->msi_attrib.default_vector = dev->irq; | 580 | entry->msi_attrib.default_irq = dev->irq; |
581 | entry->msi_attrib.pos = pos; | ||
846 | entry->dev = dev; | 582 | entry->dev = dev; |
847 | entry->mask_base = base; | 583 | entry->mask_base = base; |
848 | if (!head) { | 584 | if (!head) { |
849 | entry->link.head = vector; | 585 | entry->link.head = irq; |
850 | entry->link.tail = vector; | 586 | entry->link.tail = irq; |
851 | head = entry; | 587 | head = entry; |
852 | } else { | 588 | } else { |
853 | entry->link.head = temp; | 589 | entry->link.head = temp; |
854 | entry->link.tail = tail->link.tail; | 590 | entry->link.tail = tail->link.tail; |
855 | tail->link.tail = vector; | 591 | tail->link.tail = irq; |
856 | head->link.head = vector; | 592 | head->link.head = irq; |
857 | } | 593 | } |
858 | temp = vector; | 594 | temp = irq; |
859 | tail = entry; | 595 | tail = entry; |
860 | /* Replace with MSI-X handler */ | ||
861 | irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); | ||
862 | /* Configure MSI-X capability structure */ | 596 | /* Configure MSI-X capability structure */ |
863 | status = msi_ops->setup(dev, vector, | 597 | status = arch_setup_msi_irq(irq, dev); |
864 | &address_hi, | 598 | if (status < 0) { |
865 | &address_lo, | 599 | destroy_msi_irq(irq); |
866 | &data); | ||
867 | if (status < 0) | ||
868 | break; | 600 | break; |
601 | } | ||
869 | 602 | ||
870 | writel(address_lo, | 603 | attach_msi_entry(entry, irq); |
871 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
872 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | ||
873 | writel(address_hi, | ||
874 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
875 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
876 | writel(data, | ||
877 | base + j * PCI_MSIX_ENTRY_SIZE + | ||
878 | PCI_MSIX_ENTRY_DATA_OFFSET); | ||
879 | attach_msi_entry(entry, vector); | ||
880 | } | 604 | } |
881 | if (i != nvec) { | 605 | if (i != nvec) { |
606 | int avail = i - 1; | ||
882 | i--; | 607 | i--; |
883 | for (; i >= 0; i--) { | 608 | for (; i >= 0; i--) { |
884 | vector = (entries + i)->vector; | 609 | irq = (entries + i)->vector; |
885 | msi_free_vector(dev, vector, 0); | 610 | msi_free_irq(dev, irq); |
886 | (entries + i)->vector = 0; | 611 | (entries + i)->vector = 0; |
887 | } | 612 | } |
888 | return -EBUSY; | 613 | /* If we had some success report the number of irqs |
614 | * we succeeded in setting up. | ||
615 | */ | ||
616 | if (avail <= 0) | ||
617 | avail = -EBUSY; | ||
618 | return avail; | ||
889 | } | 619 | } |
890 | /* Set MSI-X enabled bits */ | 620 | /* Set MSI-X enabled bits */ |
891 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | 621 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); |
@@ -925,15 +655,14 @@ int pci_msi_supported(struct pci_dev * dev) | |||
925 | * @dev: pointer to the pci_dev data structure of MSI device function | 655 | * @dev: pointer to the pci_dev data structure of MSI device function |
926 | * | 656 | * |
927 | * Setup the MSI capability structure of device function with | 657 | * Setup the MSI capability structure of device function with |
928 | * a single MSI vector upon its software driver call to request for | 658 | * a single MSI irq upon its software driver call to request for |
929 | * MSI mode enabled on its hardware device function. A return of zero | 659 | * MSI mode enabled on its hardware device function. A return of zero |
930 | * indicates the successful setup of an entry zero with the new MSI | 660 | * indicates the successful setup of an entry zero with the new MSI |
931 | * vector or non-zero for otherwise. | 661 | * irq or non-zero for otherwise. |
932 | **/ | 662 | **/ |
933 | int pci_enable_msi(struct pci_dev* dev) | 663 | int pci_enable_msi(struct pci_dev* dev) |
934 | { | 664 | { |
935 | int pos, temp, status; | 665 | int pos, temp, status; |
936 | u16 control; | ||
937 | 666 | ||
938 | if (pci_msi_supported(dev) < 0) | 667 | if (pci_msi_supported(dev) < 0) |
939 | return -EINVAL; | 668 | return -EINVAL; |
@@ -948,52 +677,25 @@ int pci_enable_msi(struct pci_dev* dev) | |||
948 | if (!pos) | 677 | if (!pos) |
949 | return -EINVAL; | 678 | return -EINVAL; |
950 | 679 | ||
951 | if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { | 680 | WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI)); |
952 | /* Lookup Sucess */ | ||
953 | unsigned long flags; | ||
954 | 681 | ||
955 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 682 | /* Check whether driver already requested for MSI-X irqs */ |
956 | if (control & PCI_MSI_FLAGS_ENABLE) | ||
957 | return 0; /* Already in MSI mode */ | ||
958 | spin_lock_irqsave(&msi_lock, flags); | ||
959 | if (!vector_irq[dev->irq]) { | ||
960 | msi_desc[dev->irq]->msi_attrib.state = 0; | ||
961 | vector_irq[dev->irq] = -1; | ||
962 | nr_released_vectors--; | ||
963 | spin_unlock_irqrestore(&msi_lock, flags); | ||
964 | status = msi_register_init(dev, msi_desc[dev->irq]); | ||
965 | if (status == 0) | ||
966 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | ||
967 | return status; | ||
968 | } | ||
969 | spin_unlock_irqrestore(&msi_lock, flags); | ||
970 | dev->irq = temp; | ||
971 | } | ||
972 | /* Check whether driver already requested for MSI-X vectors */ | ||
973 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 683 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); |
974 | if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 684 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
975 | printk(KERN_INFO "PCI: %s: Can't enable MSI. " | 685 | printk(KERN_INFO "PCI: %s: Can't enable MSI. " |
976 | "Device already has MSI-X vectors assigned\n", | 686 | "Device already has MSI-X irq assigned\n", |
977 | pci_name(dev)); | 687 | pci_name(dev)); |
978 | dev->irq = temp; | 688 | dev->irq = temp; |
979 | return -EINVAL; | 689 | return -EINVAL; |
980 | } | 690 | } |
981 | status = msi_capability_init(dev); | 691 | status = msi_capability_init(dev); |
982 | if (!status) { | ||
983 | if (!pos) | ||
984 | nr_reserved_vectors--; /* Only MSI capable */ | ||
985 | else if (nr_msix_devices > 0) | ||
986 | nr_msix_devices--; /* Both MSI and MSI-X capable, | ||
987 | but choose enabling MSI */ | ||
988 | } | ||
989 | |||
990 | return status; | 692 | return status; |
991 | } | 693 | } |
992 | 694 | ||
993 | void pci_disable_msi(struct pci_dev* dev) | 695 | void pci_disable_msi(struct pci_dev* dev) |
994 | { | 696 | { |
995 | struct msi_desc *entry; | 697 | struct msi_desc *entry; |
996 | int pos, default_vector; | 698 | int pos, default_irq; |
997 | u16 control; | 699 | u16 control; |
998 | unsigned long flags; | 700 | unsigned long flags; |
999 | 701 | ||
@@ -1010,41 +712,41 @@ void pci_disable_msi(struct pci_dev* dev) | |||
1010 | if (!(control & PCI_MSI_FLAGS_ENABLE)) | 712 | if (!(control & PCI_MSI_FLAGS_ENABLE)) |
1011 | return; | 713 | return; |
1012 | 714 | ||
715 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | ||
716 | |||
1013 | spin_lock_irqsave(&msi_lock, flags); | 717 | spin_lock_irqsave(&msi_lock, flags); |
1014 | entry = msi_desc[dev->irq]; | 718 | entry = msi_desc[dev->irq]; |
1015 | if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { | 719 | if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { |
1016 | spin_unlock_irqrestore(&msi_lock, flags); | 720 | spin_unlock_irqrestore(&msi_lock, flags); |
1017 | return; | 721 | return; |
1018 | } | 722 | } |
1019 | if (entry->msi_attrib.state) { | 723 | if (irq_has_action(dev->irq)) { |
1020 | spin_unlock_irqrestore(&msi_lock, flags); | 724 | spin_unlock_irqrestore(&msi_lock, flags); |
1021 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " | 725 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " |
1022 | "free_irq() on MSI vector %d\n", | 726 | "free_irq() on MSI irq %d\n", |
1023 | pci_name(dev), dev->irq); | 727 | pci_name(dev), dev->irq); |
1024 | BUG_ON(entry->msi_attrib.state > 0); | 728 | BUG_ON(irq_has_action(dev->irq)); |
1025 | } else { | 729 | } else { |
1026 | vector_irq[dev->irq] = 0; /* free it */ | 730 | default_irq = entry->msi_attrib.default_irq; |
1027 | nr_released_vectors++; | ||
1028 | default_vector = entry->msi_attrib.default_vector; | ||
1029 | spin_unlock_irqrestore(&msi_lock, flags); | 731 | spin_unlock_irqrestore(&msi_lock, flags); |
1030 | /* Restore dev->irq to its default pin-assertion vector */ | 732 | msi_free_irq(dev, dev->irq); |
1031 | dev->irq = default_vector; | 733 | |
1032 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | 734 | /* Restore dev->irq to its default pin-assertion irq */ |
1033 | PCI_CAP_ID_MSI); | 735 | dev->irq = default_irq; |
1034 | } | 736 | } |
1035 | } | 737 | } |
1036 | 738 | ||
1037 | static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) | 739 | static int msi_free_irq(struct pci_dev* dev, int irq) |
1038 | { | 740 | { |
1039 | struct msi_desc *entry; | 741 | struct msi_desc *entry; |
1040 | int head, entry_nr, type; | 742 | int head, entry_nr, type; |
1041 | void __iomem *base; | 743 | void __iomem *base; |
1042 | unsigned long flags; | 744 | unsigned long flags; |
1043 | 745 | ||
1044 | msi_ops->teardown(vector); | 746 | arch_teardown_msi_irq(irq); |
1045 | 747 | ||
1046 | spin_lock_irqsave(&msi_lock, flags); | 748 | spin_lock_irqsave(&msi_lock, flags); |
1047 | entry = msi_desc[vector]; | 749 | entry = msi_desc[irq]; |
1048 | if (!entry || entry->dev != dev) { | 750 | if (!entry || entry->dev != dev) { |
1049 | spin_unlock_irqrestore(&msi_lock, flags); | 751 | spin_unlock_irqrestore(&msi_lock, flags); |
1050 | return -EINVAL; | 752 | return -EINVAL; |
@@ -1056,100 +758,42 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) | |||
1056 | msi_desc[entry->link.head]->link.tail = entry->link.tail; | 758 | msi_desc[entry->link.head]->link.tail = entry->link.tail; |
1057 | msi_desc[entry->link.tail]->link.head = entry->link.head; | 759 | msi_desc[entry->link.tail]->link.head = entry->link.head; |
1058 | entry->dev = NULL; | 760 | entry->dev = NULL; |
1059 | if (!reassign) { | 761 | msi_desc[irq] = NULL; |
1060 | vector_irq[vector] = 0; | ||
1061 | nr_released_vectors++; | ||
1062 | } | ||
1063 | msi_desc[vector] = NULL; | ||
1064 | spin_unlock_irqrestore(&msi_lock, flags); | 762 | spin_unlock_irqrestore(&msi_lock, flags); |
1065 | 763 | ||
1066 | kmem_cache_free(msi_cachep, entry); | 764 | destroy_msi_irq(irq); |
1067 | 765 | ||
1068 | if (type == PCI_CAP_ID_MSIX) { | 766 | if (type == PCI_CAP_ID_MSIX) { |
1069 | if (!reassign) | 767 | writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + |
1070 | writel(1, base + | 768 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); |
1071 | entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
1072 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); | ||
1073 | 769 | ||
1074 | if (head == vector) | 770 | if (head == irq) |
1075 | iounmap(base); | 771 | iounmap(base); |
1076 | } | 772 | } |
1077 | 773 | ||
1078 | return 0; | 774 | return 0; |
1079 | } | 775 | } |
1080 | 776 | ||
1081 | static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) | ||
1082 | { | ||
1083 | int vector = head, tail = 0; | ||
1084 | int i, j = 0, nr_entries = 0; | ||
1085 | void __iomem *base; | ||
1086 | unsigned long flags; | ||
1087 | |||
1088 | spin_lock_irqsave(&msi_lock, flags); | ||
1089 | while (head != tail) { | ||
1090 | nr_entries++; | ||
1091 | tail = msi_desc[vector]->link.tail; | ||
1092 | if (entries[0].entry == msi_desc[vector]->msi_attrib.entry_nr) | ||
1093 | j = vector; | ||
1094 | vector = tail; | ||
1095 | } | ||
1096 | if (*nvec > nr_entries) { | ||
1097 | spin_unlock_irqrestore(&msi_lock, flags); | ||
1098 | *nvec = nr_entries; | ||
1099 | return -EINVAL; | ||
1100 | } | ||
1101 | vector = ((j > 0) ? j : head); | ||
1102 | for (i = 0; i < *nvec; i++) { | ||
1103 | j = msi_desc[vector]->msi_attrib.entry_nr; | ||
1104 | msi_desc[vector]->msi_attrib.state = 0; /* Mark it not active */ | ||
1105 | vector_irq[vector] = -1; /* Mark it busy */ | ||
1106 | nr_released_vectors--; | ||
1107 | entries[i].vector = vector; | ||
1108 | if (j != (entries + i)->entry) { | ||
1109 | base = msi_desc[vector]->mask_base; | ||
1110 | msi_desc[vector]->msi_attrib.entry_nr = | ||
1111 | (entries + i)->entry; | ||
1112 | writel( readl(base + j * PCI_MSIX_ENTRY_SIZE + | ||
1113 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET), base + | ||
1114 | (entries + i)->entry * PCI_MSIX_ENTRY_SIZE + | ||
1115 | PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); | ||
1116 | writel( readl(base + j * PCI_MSIX_ENTRY_SIZE + | ||
1117 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET), base + | ||
1118 | (entries + i)->entry * PCI_MSIX_ENTRY_SIZE + | ||
1119 | PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); | ||
1120 | writel( (readl(base + j * PCI_MSIX_ENTRY_SIZE + | ||
1121 | PCI_MSIX_ENTRY_DATA_OFFSET) & 0xff00) | vector, | ||
1122 | base + (entries+i)->entry*PCI_MSIX_ENTRY_SIZE + | ||
1123 | PCI_MSIX_ENTRY_DATA_OFFSET); | ||
1124 | } | ||
1125 | vector = msi_desc[vector]->link.tail; | ||
1126 | } | ||
1127 | spin_unlock_irqrestore(&msi_lock, flags); | ||
1128 | |||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | /** | 777 | /** |
1133 | * pci_enable_msix - configure device's MSI-X capability structure | 778 | * pci_enable_msix - configure device's MSI-X capability structure |
1134 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 779 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
1135 | * @entries: pointer to an array of MSI-X entries | 780 | * @entries: pointer to an array of MSI-X entries |
1136 | * @nvec: number of MSI-X vectors requested for allocation by device driver | 781 | * @nvec: number of MSI-X irqs requested for allocation by device driver |
1137 | * | 782 | * |
1138 | * Setup the MSI-X capability structure of device function with the number | 783 | * Setup the MSI-X capability structure of device function with the number |
1139 | * of requested vectors upon its software driver call to request for | 784 | * of requested irqs upon its software driver call to request for |
1140 | * MSI-X mode enabled on its hardware device function. A return of zero | 785 | * MSI-X mode enabled on its hardware device function. A return of zero |
1141 | * indicates the successful configuration of MSI-X capability structure | 786 | * indicates the successful configuration of MSI-X capability structure |
1142 | * with new allocated MSI-X vectors. A return of < 0 indicates a failure. | 787 | * with new allocated MSI-X irqs. A return of < 0 indicates a failure. |
1143 | * Or a return of > 0 indicates that driver request is exceeding the number | 788 | * Or a return of > 0 indicates that driver request is exceeding the number |
1144 | * of vectors available. Driver should use the returned value to re-send | 789 | * of irqs available. Driver should use the returned value to re-send |
1145 | * its request. | 790 | * its request. |
1146 | **/ | 791 | **/ |
1147 | int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | 792 | int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) |
1148 | { | 793 | { |
1149 | int status, pos, nr_entries, free_vectors; | 794 | int status, pos, nr_entries; |
1150 | int i, j, temp; | 795 | int i, j, temp; |
1151 | u16 control; | 796 | u16 control; |
1152 | unsigned long flags; | ||
1153 | 797 | ||
1154 | if (!entries || pci_msi_supported(dev) < 0) | 798 | if (!entries || pci_msi_supported(dev) < 0) |
1155 | return -EINVAL; | 799 | return -EINVAL; |
@@ -1163,9 +807,6 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | |||
1163 | return -EINVAL; | 807 | return -EINVAL; |
1164 | 808 | ||
1165 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 809 | pci_read_config_word(dev, msi_control_reg(pos), &control); |
1166 | if (control & PCI_MSIX_FLAGS_ENABLE) | ||
1167 | return -EINVAL; /* Already in MSI-X mode */ | ||
1168 | |||
1169 | nr_entries = multi_msix_capable(control); | 810 | nr_entries = multi_msix_capable(control); |
1170 | if (nvec > nr_entries) | 811 | if (nvec > nr_entries) |
1171 | return -EINVAL; | 812 | return -EINVAL; |
@@ -1180,56 +821,18 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | |||
1180 | } | 821 | } |
1181 | } | 822 | } |
1182 | temp = dev->irq; | 823 | temp = dev->irq; |
1183 | if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 824 | WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)); |
1184 | /* Lookup Sucess */ | 825 | |
1185 | nr_entries = nvec; | 826 | /* Check whether driver already requested for MSI irq */ |
1186 | /* Reroute MSI-X table */ | ||
1187 | if (reroute_msix_table(dev->irq, entries, &nr_entries)) { | ||
1188 | /* #requested > #previous-assigned */ | ||
1189 | dev->irq = temp; | ||
1190 | return nr_entries; | ||
1191 | } | ||
1192 | dev->irq = temp; | ||
1193 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | ||
1194 | return 0; | ||
1195 | } | ||
1196 | /* Check whether driver already requested for MSI vector */ | ||
1197 | if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && | 827 | if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && |
1198 | !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { | 828 | !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { |
1199 | printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " | 829 | printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " |
1200 | "Device already has an MSI vector assigned\n", | 830 | "Device already has an MSI irq assigned\n", |
1201 | pci_name(dev)); | 831 | pci_name(dev)); |
1202 | dev->irq = temp; | 832 | dev->irq = temp; |
1203 | return -EINVAL; | 833 | return -EINVAL; |
1204 | } | 834 | } |
1205 | |||
1206 | spin_lock_irqsave(&msi_lock, flags); | ||
1207 | /* | ||
1208 | * msi_lock is provided to ensure that enough vectors resources are | ||
1209 | * available before granting. | ||
1210 | */ | ||
1211 | free_vectors = pci_vector_resources(last_alloc_vector, | ||
1212 | nr_released_vectors); | ||
1213 | /* Ensure that each MSI/MSI-X device has one vector reserved by | ||
1214 | default to avoid any MSI-X driver to take all available | ||
1215 | resources */ | ||
1216 | free_vectors -= nr_reserved_vectors; | ||
1217 | /* Find the average of free vectors among MSI-X devices */ | ||
1218 | if (nr_msix_devices > 0) | ||
1219 | free_vectors /= nr_msix_devices; | ||
1220 | spin_unlock_irqrestore(&msi_lock, flags); | ||
1221 | |||
1222 | if (nvec > free_vectors) { | ||
1223 | if (free_vectors > 0) | ||
1224 | return free_vectors; | ||
1225 | else | ||
1226 | return -EBUSY; | ||
1227 | } | ||
1228 | |||
1229 | status = msix_capability_init(dev, entries, nvec); | 835 | status = msix_capability_init(dev, entries, nvec); |
1230 | if (!status && nr_msix_devices > 0) | ||
1231 | nr_msix_devices--; | ||
1232 | |||
1233 | return status; | 836 | return status; |
1234 | } | 837 | } |
1235 | 838 | ||
@@ -1251,53 +854,47 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1251 | if (!(control & PCI_MSIX_FLAGS_ENABLE)) | 854 | if (!(control & PCI_MSIX_FLAGS_ENABLE)) |
1252 | return; | 855 | return; |
1253 | 856 | ||
857 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | ||
858 | |||
1254 | temp = dev->irq; | 859 | temp = dev->irq; |
1255 | if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 860 | if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
1256 | int state, vector, head, tail = 0, warning = 0; | 861 | int irq, head, tail = 0, warning = 0; |
1257 | unsigned long flags; | 862 | unsigned long flags; |
1258 | 863 | ||
1259 | vector = head = dev->irq; | 864 | irq = head = dev->irq; |
1260 | spin_lock_irqsave(&msi_lock, flags); | 865 | dev->irq = temp; /* Restore pin IRQ */ |
1261 | while (head != tail) { | 866 | while (head != tail) { |
1262 | state = msi_desc[vector]->msi_attrib.state; | 867 | spin_lock_irqsave(&msi_lock, flags); |
1263 | if (state) | 868 | tail = msi_desc[irq]->link.tail; |
869 | spin_unlock_irqrestore(&msi_lock, flags); | ||
870 | if (irq_has_action(irq)) | ||
1264 | warning = 1; | 871 | warning = 1; |
1265 | else { | 872 | else if (irq != head) /* Release MSI-X irq */ |
1266 | vector_irq[vector] = 0; /* free it */ | 873 | msi_free_irq(dev, irq); |
1267 | nr_released_vectors++; | 874 | irq = tail; |
1268 | } | ||
1269 | tail = msi_desc[vector]->link.tail; | ||
1270 | vector = tail; | ||
1271 | } | 875 | } |
1272 | spin_unlock_irqrestore(&msi_lock, flags); | 876 | msi_free_irq(dev, irq); |
1273 | if (warning) { | 877 | if (warning) { |
1274 | dev->irq = temp; | ||
1275 | printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " | 878 | printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " |
1276 | "free_irq() on all MSI-X vectors\n", | 879 | "free_irq() on all MSI-X irqs\n", |
1277 | pci_name(dev)); | 880 | pci_name(dev)); |
1278 | BUG_ON(warning > 0); | 881 | BUG_ON(warning > 0); |
1279 | } else { | ||
1280 | dev->irq = temp; | ||
1281 | disable_msi_mode(dev, | ||
1282 | pci_find_capability(dev, PCI_CAP_ID_MSIX), | ||
1283 | PCI_CAP_ID_MSIX); | ||
1284 | |||
1285 | } | 882 | } |
1286 | } | 883 | } |
1287 | } | 884 | } |
1288 | 885 | ||
1289 | /** | 886 | /** |
1290 | * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state | 887 | * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state |
1291 | * @dev: pointer to the pci_dev data structure of MSI(X) device function | 888 | * @dev: pointer to the pci_dev data structure of MSI(X) device function |
1292 | * | 889 | * |
1293 | * Being called during hotplug remove, from which the device function | 890 | * Being called during hotplug remove, from which the device function |
1294 | * is hot-removed. All previous assigned MSI/MSI-X vectors, if | 891 | * is hot-removed. All previous assigned MSI/MSI-X irqs, if |
1295 | * allocated for this device function, are reclaimed to unused state, | 892 | * allocated for this device function, are reclaimed to unused state, |
1296 | * which may be used later on. | 893 | * which may be used later on. |
1297 | **/ | 894 | **/ |
1298 | void msi_remove_pci_irq_vectors(struct pci_dev* dev) | 895 | void msi_remove_pci_irq_vectors(struct pci_dev* dev) |
1299 | { | 896 | { |
1300 | int state, pos, temp; | 897 | int pos, temp; |
1301 | unsigned long flags; | 898 | unsigned long flags; |
1302 | 899 | ||
1303 | if (!pci_msi_enable || !dev) | 900 | if (!pci_msi_enable || !dev) |
@@ -1305,42 +902,38 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) | |||
1305 | 902 | ||
1306 | temp = dev->irq; /* Save IOAPIC IRQ */ | 903 | temp = dev->irq; /* Save IOAPIC IRQ */ |
1307 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 904 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
1308 | if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { | 905 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { |
1309 | spin_lock_irqsave(&msi_lock, flags); | 906 | if (irq_has_action(dev->irq)) { |
1310 | state = msi_desc[dev->irq]->msi_attrib.state; | ||
1311 | spin_unlock_irqrestore(&msi_lock, flags); | ||
1312 | if (state) { | ||
1313 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " | 907 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " |
1314 | "called without free_irq() on MSI vector %d\n", | 908 | "called without free_irq() on MSI irq %d\n", |
1315 | pci_name(dev), dev->irq); | 909 | pci_name(dev), dev->irq); |
1316 | BUG_ON(state > 0); | 910 | BUG_ON(irq_has_action(dev->irq)); |
1317 | } else /* Release MSI vector assigned to this device */ | 911 | } else /* Release MSI irq assigned to this device */ |
1318 | msi_free_vector(dev, dev->irq, 0); | 912 | msi_free_irq(dev, dev->irq); |
1319 | dev->irq = temp; /* Restore IOAPIC IRQ */ | 913 | dev->irq = temp; /* Restore IOAPIC IRQ */ |
1320 | } | 914 | } |
1321 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 915 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); |
1322 | if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 916 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
1323 | int vector, head, tail = 0, warning = 0; | 917 | int irq, head, tail = 0, warning = 0; |
1324 | void __iomem *base = NULL; | 918 | void __iomem *base = NULL; |
1325 | 919 | ||
1326 | vector = head = dev->irq; | 920 | irq = head = dev->irq; |
1327 | while (head != tail) { | 921 | while (head != tail) { |
1328 | spin_lock_irqsave(&msi_lock, flags); | 922 | spin_lock_irqsave(&msi_lock, flags); |
1329 | state = msi_desc[vector]->msi_attrib.state; | 923 | tail = msi_desc[irq]->link.tail; |
1330 | tail = msi_desc[vector]->link.tail; | 924 | base = msi_desc[irq]->mask_base; |
1331 | base = msi_desc[vector]->mask_base; | ||
1332 | spin_unlock_irqrestore(&msi_lock, flags); | 925 | spin_unlock_irqrestore(&msi_lock, flags); |
1333 | if (state) | 926 | if (irq_has_action(irq)) |
1334 | warning = 1; | 927 | warning = 1; |
1335 | else if (vector != head) /* Release MSI-X vector */ | 928 | else if (irq != head) /* Release MSI-X irq */ |
1336 | msi_free_vector(dev, vector, 0); | 929 | msi_free_irq(dev, irq); |
1337 | vector = tail; | 930 | irq = tail; |
1338 | } | 931 | } |
1339 | msi_free_vector(dev, vector, 0); | 932 | msi_free_irq(dev, irq); |
1340 | if (warning) { | 933 | if (warning) { |
1341 | iounmap(base); | 934 | iounmap(base); |
1342 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " | 935 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " |
1343 | "called without free_irq() on all MSI-X vectors\n", | 936 | "called without free_irq() on all MSI-X irqs\n", |
1344 | pci_name(dev)); | 937 | pci_name(dev)); |
1345 | BUG_ON(warning > 0); | 938 | BUG_ON(warning > 0); |
1346 | } | 939 | } |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index 56951c39d3a..f0cca1772f9 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
@@ -7,84 +7,6 @@ | |||
7 | #define MSI_H | 7 | #define MSI_H |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * MSI operation vector. Used by the msi core code (drivers/pci/msi.c) | ||
11 | * to abstract platform-specific tasks relating to MSI address generation | ||
12 | * and resource management. | ||
13 | */ | ||
14 | struct msi_ops { | ||
15 | /** | ||
16 | * setup - generate an MSI bus address and data for a given vector | ||
17 | * @pdev: PCI device context (in) | ||
18 | * @vector: vector allocated by the msi core (in) | ||
19 | * @addr_hi: upper 32 bits of PCI bus MSI address (out) | ||
20 | * @addr_lo: lower 32 bits of PCI bus MSI address (out) | ||
21 | * @data: MSI data payload (out) | ||
22 | * | ||
23 | * Description: The setup op is used to generate a PCI bus addres and | ||
24 | * data which the msi core will program into the card MSI capability | ||
25 | * registers. The setup routine is responsible for picking an initial | ||
26 | * cpu to target the MSI at. The setup routine is responsible for | ||
27 | * examining pdev to determine the MSI capabilities of the card and | ||
28 | * generating a suitable address/data. The setup routine is | ||
29 | * responsible for allocating and tracking any system resources it | ||
30 | * needs to route the MSI to the cpu it picks, and for associating | ||
31 | * those resources with the passed in vector. | ||
32 | * | ||
33 | * Returns 0 if the MSI address/data was successfully setup. | ||
34 | **/ | ||
35 | |||
36 | int (*setup) (struct pci_dev *pdev, unsigned int vector, | ||
37 | u32 *addr_hi, u32 *addr_lo, u32 *data); | ||
38 | |||
39 | /** | ||
40 | * teardown - release resources allocated by setup | ||
41 | * @vector: vector context for resources (in) | ||
42 | * | ||
43 | * Description: The teardown op is used to release any resources | ||
44 | * that were allocated in the setup routine associated with the passed | ||
45 | * in vector. | ||
46 | **/ | ||
47 | |||
48 | void (*teardown) (unsigned int vector); | ||
49 | |||
50 | /** | ||
51 | * target - retarget an MSI at a different cpu | ||
52 | * @vector: vector context for resources (in) | ||
53 | * @cpu: new cpu to direct vector at (in) | ||
54 | * @addr_hi: new value of PCI bus upper 32 bits (in/out) | ||
55 | * @addr_lo: new value of PCI bus lower 32 bits (in/out) | ||
56 | * | ||
57 | * Description: The target op is used to redirect an MSI vector | ||
58 | * at a different cpu. addr_hi/addr_lo coming in are the existing | ||
59 | * values that the MSI core has programmed into the card. The | ||
60 | * target code is responsible for freeing any resources (if any) | ||
61 | * associated with the old address, and generating a new PCI bus | ||
62 | * addr_hi/addr_lo that will redirect the vector at the indicated cpu. | ||
63 | **/ | ||
64 | |||
65 | void (*target) (unsigned int vector, unsigned int cpu, | ||
66 | u32 *addr_hi, u32 *addr_lo); | ||
67 | }; | ||
68 | |||
69 | extern int msi_register(struct msi_ops *ops); | ||
70 | |||
71 | #include <asm/msi.h> | ||
72 | |||
73 | /* | ||
74 | * Assume the maximum number of hot plug slots supported by the system is about | ||
75 | * ten. The worstcase is that each of these slots is hot-added with a device, | ||
76 | * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which | ||
77 | * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined | ||
78 | * as below to ensure at least one message is assigned to each detected MSI/ | ||
79 | * MSI-X device function. | ||
80 | */ | ||
81 | #define NR_HP_RESERVED_VECTORS 20 | ||
82 | |||
83 | extern int vector_irq[NR_VECTORS]; | ||
84 | extern void (*interrupt[NR_IRQS])(void); | ||
85 | extern int pci_vector_resources(int last, int nr_released); | ||
86 | |||
87 | /* | ||
88 | * MSI-X Address Register | 10 | * MSI-X Address Register |
89 | */ | 11 | */ |
90 | #define PCI_MSIX_FLAGS_QSIZE 0x7FF | 12 | #define PCI_MSIX_FLAGS_QSIZE 0x7FF |
@@ -110,8 +32,8 @@ extern int pci_vector_resources(int last, int nr_released); | |||
110 | (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) | 32 | (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) |
111 | #define multi_msi_enable(control, num) \ | 33 | #define multi_msi_enable(control, num) \ |
112 | control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE); | 34 | control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE); |
113 | #define is_64bit_address(control) (control & PCI_MSI_FLAGS_64BIT) | 35 | #define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) |
114 | #define is_mask_bit_support(control) (control & PCI_MSI_FLAGS_MASKBIT) | 36 | #define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) |
115 | #define msi_enable(control, num) multi_msi_enable(control, num); \ | 37 | #define msi_enable(control, num) multi_msi_enable(control, num); \ |
116 | control |= PCI_MSI_FLAGS_ENABLE | 38 | control |= PCI_MSI_FLAGS_ENABLE |
117 | 39 | ||
@@ -125,32 +47,4 @@ extern int pci_vector_resources(int last, int nr_released); | |||
125 | #define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) | 47 | #define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) |
126 | #define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) | 48 | #define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) |
127 | 49 | ||
128 | struct msi_desc { | ||
129 | struct { | ||
130 | __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ | ||
131 | __u8 maskbit : 1; /* mask-pending bit supported ? */ | ||
132 | __u8 state : 1; /* {0: free, 1: busy} */ | ||
133 | __u8 reserved: 1; /* reserved */ | ||
134 | __u8 entry_nr; /* specific enabled entry */ | ||
135 | __u8 default_vector; /* default pre-assigned vector */ | ||
136 | __u8 unused; /* formerly unused destination cpu*/ | ||
137 | }msi_attrib; | ||
138 | |||
139 | struct { | ||
140 | __u16 head; | ||
141 | __u16 tail; | ||
142 | }link; | ||
143 | |||
144 | void __iomem *mask_base; | ||
145 | struct pci_dev *dev; | ||
146 | |||
147 | #ifdef CONFIG_PM | ||
148 | /* PM save area for MSIX address/data */ | ||
149 | |||
150 | u32 address_hi_save; | ||
151 | u32 address_lo_save; | ||
152 | u32 data_save; | ||
153 | #endif | ||
154 | }; | ||
155 | |||
156 | #endif /* MSI_H */ | 50 | #endif /* MSI_H */ |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 54404917be9..8f7bcf56f14 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -55,16 +55,16 @@ pbus_assign_resources_sorted(struct pci_bus *bus) | |||
55 | list_for_each_entry(dev, &bus->devices, bus_list) { | 55 | list_for_each_entry(dev, &bus->devices, bus_list) { |
56 | u16 class = dev->class >> 8; | 56 | u16 class = dev->class >> 8; |
57 | 57 | ||
58 | /* Don't touch classless devices or host bridges. */ | 58 | /* Don't touch classless devices or host bridges or ioapics. */ |
59 | if (class == PCI_CLASS_NOT_DEFINED || | 59 | if (class == PCI_CLASS_NOT_DEFINED || |
60 | class == PCI_CLASS_BRIDGE_HOST) | 60 | class == PCI_CLASS_BRIDGE_HOST) |
61 | continue; | 61 | continue; |
62 | 62 | ||
63 | /* Don't touch ioapics if it has the assigned resources. */ | 63 | /* Don't touch ioapic devices already enabled by firmware */ |
64 | if (class == PCI_CLASS_SYSTEM_PIC) { | 64 | if (class == PCI_CLASS_SYSTEM_PIC) { |
65 | res = &dev->resource[0]; | 65 | u16 command; |
66 | if (res[0].start || res[1].start || res[2].start || | 66 | pci_read_config_word(dev, PCI_COMMAND, &command); |
67 | res[3].start || res[4].start || res[5].start) | 67 | if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) |
68 | continue; | 68 | continue; |
69 | } | 69 | } |
70 | 70 | ||
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index cc5032b6f42..3f0f7b8fa81 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -141,9 +141,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
141 | 141 | ||
142 | dev_dbg(dev, "%s secs=%d, mins=%d, " | 142 | dev_dbg(dev, "%s secs=%d, mins=%d, " |
143 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | 143 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", |
144 | "write", dt->tm_sec, dt->tm_min, | 144 | "write", t->tm_sec, t->tm_min, |
145 | dt->tm_hour, dt->tm_mday, | 145 | t->tm_hour, t->tm_mday, |
146 | dt->tm_mon, dt->tm_year, dt->tm_wday); | 146 | t->tm_mon, t->tm_year, t->tm_wday); |
147 | 147 | ||
148 | *buf++ = 0; /* first register addr */ | 148 | *buf++ = 0; /* first register addr */ |
149 | buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec); | 149 | buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec); |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 9c68ec99afa..67e816a9a39 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -55,7 +55,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | dev_dbg(&client->dev, | 57 | dev_dbg(&client->dev, |
58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" | 58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n", |
59 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); | 59 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); |
60 | 60 | ||
61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | 61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
@@ -96,7 +96,7 @@ static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
96 | unsigned long secs; | 96 | unsigned long secs; |
97 | 97 | ||
98 | dev_dbg(&client->dev, | 98 | dev_dbg(&client->dev, |
99 | "%s: secs=%d, mins=%d, hours=%d, ", | 99 | "%s: secs=%d, mins=%d, hours=%d, " |
100 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 100 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
101 | __FUNCTION__, | 101 | __FUNCTION__, |
102 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 102 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index bbdad099471..2a86632580f 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -91,7 +91,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
91 | unsigned char buf[8] = { RS5C372_REG_BASE }; | 91 | unsigned char buf[8] = { RS5C372_REG_BASE }; |
92 | 92 | ||
93 | dev_dbg(&client->dev, | 93 | dev_dbg(&client->dev, |
94 | "%s: secs=%d, mins=%d, hours=%d ", | 94 | "%s: secs=%d, mins=%d, hours=%d " |
95 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 95 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
96 | __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, | 96 | __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, |
97 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 97 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
@@ -126,7 +126,7 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) | |||
126 | return -EIO; | 126 | return -EIO; |
127 | } | 127 | } |
128 | 128 | ||
129 | dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, trim); | 129 | dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); |
130 | 130 | ||
131 | if (osc) | 131 | if (osc) |
132 | *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; | 132 | *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; |
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 1ebe6b585d2..c5d0addfda4 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <asm/hardware.h> | 22 | #include <asm/hardware.h> |
23 | #include <asm/parisc-device.h> | 23 | #include <asm/parisc-device.h> |
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/serial.h> /* for LASI_BASE_BAUD */ | ||
26 | 25 | ||
27 | #include "8250.h" | 26 | #include "8250.h" |
28 | 27 | ||
@@ -54,7 +53,8 @@ serial_init_chip(struct parisc_device *dev) | |||
54 | 53 | ||
55 | memset(&port, 0, sizeof(port)); | 54 | memset(&port, 0, sizeof(port)); |
56 | port.iotype = UPIO_MEM; | 55 | port.iotype = UPIO_MEM; |
57 | port.uartclk = LASI_BASE_BAUD * 16; | 56 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ |
57 | port.uartclk = 7272727; | ||
58 | port.mapbase = address; | 58 | port.mapbase = address; |
59 | port.membase = ioremap_nocache(address, 16); | 59 | port.membase = ioremap_nocache(address, 16); |
60 | port.irq = dev->irq; | 60 | port.irq = dev->irq; |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 653098bc2dd..8edee745888 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -556,10 +556,11 @@ config SERIAL_MUX | |||
556 | default y | 556 | default y |
557 | ---help--- | 557 | ---help--- |
558 | Saying Y here will enable the hardware MUX serial driver for | 558 | Saying Y here will enable the hardware MUX serial driver for |
559 | the Nova and K class systems. The hardware MUX is not 8250/16550 | 559 | the Nova, K class systems and D class with a 'remote control card'. |
560 | compatible therefore the /dev/ttyB0 device is shared between the | 560 | The hardware MUX is not 8250/16550 compatible therefore the |
561 | Serial MUX and the PDC software console. The following steps | 561 | /dev/ttyB0 device is shared between the Serial MUX and the PDC |
562 | need to be completed to use the Serial MUX: | 562 | software console. The following steps need to be completed to use |
563 | the Serial MUX: | ||
563 | 564 | ||
564 | 1. create the device entry (mknod /dev/ttyB0 c 11 0) | 565 | 1. create the device entry (mknod /dev/ttyB0 c 11 0) |
565 | 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0 | 566 | 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0 |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index b120896c8ab..a433cc78ef9 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -1843,7 +1843,7 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) | |||
1843 | for (i = 0; propnames[i] != NULL; ++i) { | 1843 | for (i = 0; propnames[i] != NULL; ++i) { |
1844 | pedid = get_property(dp, propnames[i], NULL); | 1844 | pedid = get_property(dp, propnames[i], NULL); |
1845 | if (pedid != NULL) { | 1845 | if (pedid != NULL) { |
1846 | par->EDID = pedid; | 1846 | par->EDID = (unsigned char *)pedid; |
1847 | NVTRACE("LCD found.\n"); | 1847 | NVTRACE("LCD found.\n"); |
1848 | return 1; | 1848 | return 1; |
1849 | } | 1849 | } |