diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-29 19:54:33 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-29 19:54:33 -0500 |
| commit | d395991c117d43bfca97101a931a41d062a93852 (patch) | |
| tree | 9c8300a5c24a41c4a3a22f2668158f7fc0899987 | |
| parent | b73384f06159d8388d7d17913b7e3a07e234c1ab (diff) | |
| parent | b445c56815d84b9fce40707f99811bdc354458e0 (diff) | |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
[libata] wrap kmap_atomic(KM_IRQ0) with local_irq_save/restore()
sata_svw: Add support for HT1100 SATA controller
| -rw-r--r-- | drivers/ata/libata-scsi.c | 10 | ||||
| -rw-r--r-- | drivers/ata/sata_svw.c | 77 |
2 files changed, 73 insertions, 14 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0562b0a49f3b..7b1f1ee8131d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -1694,12 +1694,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | |||
| 1694 | u8 *rbuf; | 1694 | u8 *rbuf; |
| 1695 | unsigned int buflen, rc; | 1695 | unsigned int buflen, rc; |
| 1696 | struct scsi_cmnd *cmd = args->cmd; | 1696 | struct scsi_cmnd *cmd = args->cmd; |
| 1697 | unsigned long flags; | ||
| 1698 | |||
| 1699 | local_irq_save(flags); | ||
| 1697 | 1700 | ||
| 1698 | buflen = ata_scsi_rbuf_get(cmd, &rbuf); | 1701 | buflen = ata_scsi_rbuf_get(cmd, &rbuf); |
| 1699 | memset(rbuf, 0, buflen); | 1702 | memset(rbuf, 0, buflen); |
| 1700 | rc = actor(args, rbuf, buflen); | 1703 | rc = actor(args, rbuf, buflen); |
| 1701 | ata_scsi_rbuf_put(cmd, rbuf); | 1704 | ata_scsi_rbuf_put(cmd, rbuf); |
| 1702 | 1705 | ||
| 1706 | local_irq_restore(flags); | ||
| 1707 | |||
| 1703 | if (rc == 0) | 1708 | if (rc == 0) |
| 1704 | cmd->result = SAM_STAT_GOOD; | 1709 | cmd->result = SAM_STAT_GOOD; |
| 1705 | args->done(cmd); | 1710 | args->done(cmd); |
| @@ -2473,6 +2478,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) | |||
| 2473 | if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { | 2478 | if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { |
| 2474 | u8 *buf = NULL; | 2479 | u8 *buf = NULL; |
| 2475 | unsigned int buflen; | 2480 | unsigned int buflen; |
| 2481 | unsigned long flags; | ||
| 2482 | |||
| 2483 | local_irq_save(flags); | ||
| 2476 | 2484 | ||
| 2477 | buflen = ata_scsi_rbuf_get(cmd, &buf); | 2485 | buflen = ata_scsi_rbuf_get(cmd, &buf); |
| 2478 | 2486 | ||
| @@ -2490,6 +2498,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) | |||
| 2490 | } | 2498 | } |
| 2491 | 2499 | ||
| 2492 | ata_scsi_rbuf_put(cmd, buf); | 2500 | ata_scsi_rbuf_put(cmd, buf); |
| 2501 | |||
| 2502 | local_irq_restore(flags); | ||
| 2493 | } | 2503 | } |
| 2494 | 2504 | ||
| 2495 | cmd->result = SAM_STAT_GOOD; | 2505 | cmd->result = SAM_STAT_GOOD; |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 69f651e0bc98..840d1c4a7850 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
| @@ -45,6 +45,8 @@ | |||
| 45 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
| 46 | #include <linux/device.h> | 46 | #include <linux/device.h> |
| 47 | #include <scsi/scsi_host.h> | 47 | #include <scsi/scsi_host.h> |
| 48 | #include <scsi/scsi_cmnd.h> | ||
| 49 | #include <scsi/scsi.h> | ||
| 48 | #include <linux/libata.h> | 50 | #include <linux/libata.h> |
| 49 | 51 | ||
| 50 | #ifdef CONFIG_PPC_OF | 52 | #ifdef CONFIG_PPC_OF |
| @@ -59,6 +61,7 @@ enum { | |||
| 59 | /* ap->flags bits */ | 61 | /* ap->flags bits */ |
| 60 | K2_FLAG_SATA_8_PORTS = (1 << 24), | 62 | K2_FLAG_SATA_8_PORTS = (1 << 24), |
| 61 | K2_FLAG_NO_ATAPI_DMA = (1 << 25), | 63 | K2_FLAG_NO_ATAPI_DMA = (1 << 25), |
| 64 | K2_FLAG_BAR_POS_3 = (1 << 26), | ||
| 62 | 65 | ||
| 63 | /* Taskfile registers offsets */ | 66 | /* Taskfile registers offsets */ |
| 64 | K2_SATA_TF_CMD_OFFSET = 0x00, | 67 | K2_SATA_TF_CMD_OFFSET = 0x00, |
| @@ -88,8 +91,10 @@ enum { | |||
| 88 | /* Port stride */ | 91 | /* Port stride */ |
| 89 | K2_SATA_PORT_OFFSET = 0x100, | 92 | K2_SATA_PORT_OFFSET = 0x100, |
| 90 | 93 | ||
| 91 | board_svw4 = 0, | 94 | chip_svw4 = 0, |
| 92 | board_svw8 = 1, | 95 | chip_svw8 = 1, |
| 96 | chip_svw42 = 2, /* bar 3 */ | ||
| 97 | chip_svw43 = 3, /* bar 5 */ | ||
| 93 | }; | 98 | }; |
| 94 | 99 | ||
| 95 | static u8 k2_stat_check_status(struct ata_port *ap); | 100 | static u8 k2_stat_check_status(struct ata_port *ap); |
| @@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap); | |||
| 97 | 102 | ||
| 98 | static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) | 103 | static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) |
| 99 | { | 104 | { |
| 105 | u8 cmnd = qc->scsicmd->cmnd[0]; | ||
| 106 | |||
| 100 | if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) | 107 | if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) |
| 101 | return -1; /* ATAPI DMA not supported */ | 108 | return -1; /* ATAPI DMA not supported */ |
| 109 | else { | ||
| 110 | switch (cmnd) { | ||
| 111 | case READ_10: | ||
| 112 | case READ_12: | ||
| 113 | case READ_16: | ||
| 114 | case WRITE_10: | ||
| 115 | case WRITE_12: | ||
| 116 | case WRITE_16: | ||
| 117 | return 0; | ||
| 118 | |||
| 119 | default: | ||
| 120 | return -1; | ||
| 121 | } | ||
| 102 | 122 | ||
| 103 | return 0; | 123 | } |
| 104 | } | 124 | } |
| 105 | 125 | ||
| 106 | static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | 126 | static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
| @@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = { | |||
| 354 | }; | 374 | }; |
| 355 | 375 | ||
| 356 | static const struct ata_port_info k2_port_info[] = { | 376 | static const struct ata_port_info k2_port_info[] = { |
| 357 | /* board_svw4 */ | 377 | /* chip_svw4 */ |
| 358 | { | 378 | { |
| 359 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 379 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 360 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, | 380 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, |
| @@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = { | |||
| 363 | .udma_mask = ATA_UDMA6, | 383 | .udma_mask = ATA_UDMA6, |
| 364 | .port_ops = &k2_sata_ops, | 384 | .port_ops = &k2_sata_ops, |
| 365 | }, | 385 | }, |
| 366 | /* board_svw8 */ | 386 | /* chip_svw8 */ |
| 367 | { | 387 | { |
| 368 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 388 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 369 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | | 389 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | |
| @@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = { | |||
| 373 | .udma_mask = ATA_UDMA6, | 393 | .udma_mask = ATA_UDMA6, |
| 374 | .port_ops = &k2_sata_ops, | 394 | .port_ops = &k2_sata_ops, |
| 375 | }, | 395 | }, |
| 396 | /* chip_svw42 */ | ||
| 397 | { | ||
| 398 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
| 399 | ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, | ||
| 400 | .pio_mask = 0x1f, | ||
| 401 | .mwdma_mask = 0x07, | ||
| 402 | .udma_mask = ATA_UDMA6, | ||
| 403 | .port_ops = &k2_sata_ops, | ||
| 404 | }, | ||
| 405 | /* chip_svw43 */ | ||
| 406 | { | ||
| 407 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
| 408 | ATA_FLAG_MMIO, | ||
| 409 | .pio_mask = 0x1f, | ||
| 410 | .mwdma_mask = 0x07, | ||
| 411 | .udma_mask = ATA_UDMA6, | ||
| 412 | .port_ops = &k2_sata_ops, | ||
| 413 | }, | ||
| 376 | }; | 414 | }; |
| 377 | 415 | ||
| 378 | static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) | 416 | static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) |
| @@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en | |||
| 402 | { &k2_port_info[ent->driver_data], NULL }; | 440 | { &k2_port_info[ent->driver_data], NULL }; |
| 403 | struct ata_host *host; | 441 | struct ata_host *host; |
| 404 | void __iomem *mmio_base; | 442 | void __iomem *mmio_base; |
| 405 | int n_ports, i, rc; | 443 | int n_ports, i, rc, bar_pos; |
| 406 | 444 | ||
| 407 | if (!printed_version++) | 445 | if (!printed_version++) |
| 408 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 446 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
| @@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en | |||
| 416 | if (!host) | 454 | if (!host) |
| 417 | return -ENOMEM; | 455 | return -ENOMEM; |
| 418 | 456 | ||
| 457 | bar_pos = 5; | ||
| 458 | if (ppi[0]->flags & K2_FLAG_BAR_POS_3) | ||
| 459 | bar_pos = 3; | ||
| 419 | /* | 460 | /* |
| 420 | * If this driver happens to only be useful on Apple's K2, then | 461 | * If this driver happens to only be useful on Apple's K2, then |
| 421 | * we should check that here as it has a normal Serverworks ID | 462 | * we should check that here as it has a normal Serverworks ID |
| @@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en | |||
| 428 | * Check if we have resources mapped at all (second function may | 469 | * Check if we have resources mapped at all (second function may |
| 429 | * have been disabled by firmware) | 470 | * have been disabled by firmware) |
| 430 | */ | 471 | */ |
| 431 | if (pci_resource_len(pdev, 5) == 0) | 472 | if (pci_resource_len(pdev, bar_pos) == 0) { |
| 473 | /* In IDE mode we need to pin the device to ensure that | ||
| 474 | pcim_release does not clear the busmaster bit in config | ||
| 475 | space, clearing causes busmaster DMA to fail on | ||
| 476 | ports 3 & 4 */ | ||
| 477 | pcim_pin_device(pdev); | ||
| 432 | return -ENODEV; | 478 | return -ENODEV; |
| 479 | } | ||
| 433 | 480 | ||
| 434 | /* Request and iomap PCI regions */ | 481 | /* Request and iomap PCI regions */ |
| 435 | rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); | 482 | rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME); |
| 436 | if (rc == -EBUSY) | 483 | if (rc == -EBUSY) |
| 437 | pcim_pin_device(pdev); | 484 | pcim_pin_device(pdev); |
| 438 | if (rc) | 485 | if (rc) |
| 439 | return rc; | 486 | return rc; |
| 440 | host->iomap = pcim_iomap_table(pdev); | 487 | host->iomap = pcim_iomap_table(pdev); |
| 441 | mmio_base = host->iomap[5]; | 488 | mmio_base = host->iomap[bar_pos]; |
| 442 | 489 | ||
| 443 | /* different controllers have different number of ports - currently 4 or 8 */ | 490 | /* different controllers have different number of ports - currently 4 or 8 */ |
| 444 | /* All ports are on the same function. Multi-function device is no | 491 | /* All ports are on the same function. Multi-function device is no |
| @@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en | |||
| 483 | * controller | 530 | * controller |
| 484 | * */ | 531 | * */ |
| 485 | static const struct pci_device_id k2_sata_pci_tbl[] = { | 532 | static const struct pci_device_id k2_sata_pci_tbl[] = { |
| 486 | { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, | 533 | { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 }, |
| 487 | { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, | 534 | { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 }, |
| 488 | { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, | 535 | { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 }, |
| 489 | { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, | 536 | { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 }, |
| 490 | { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, | 537 | { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 }, |
| 538 | { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 }, | ||
| 539 | { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 }, | ||
| 491 | 540 | ||
| 492 | { } | 541 | { } |
| 493 | }; | 542 | }; |
