diff options
| -rw-r--r-- | drivers/ata/sata_inic162x.c | 81 |
1 files changed, 47 insertions, 34 deletions
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 579154c27902..cdae435620f6 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c | |||
| @@ -192,7 +192,8 @@ struct inic_prd { | |||
| 192 | 192 | ||
| 193 | struct inic_pkt { | 193 | struct inic_pkt { |
| 194 | struct inic_cpb cpb; | 194 | struct inic_cpb cpb; |
| 195 | struct inic_prd prd[LIBATA_MAX_PRD]; | 195 | struct inic_prd prd[LIBATA_MAX_PRD + 1]; /* + 1 for cdb */ |
| 196 | u8 cdb[ATAPI_CDB_LEN]; | ||
| 196 | } __packed; | 197 | } __packed; |
| 197 | 198 | ||
| 198 | struct inic_host_priv { | 199 | struct inic_host_priv { |
| @@ -361,23 +362,18 @@ static void inic_host_intr(struct ata_port *ap) | |||
| 361 | goto spurious; | 362 | goto spurious; |
| 362 | } | 363 | } |
| 363 | 364 | ||
| 364 | if (!ata_is_atapi(qc->tf.protocol)) { | 365 | if (likely(idma_stat & IDMA_STAT_DONE)) { |
| 365 | if (likely(idma_stat & IDMA_STAT_DONE)) { | 366 | inic_stop_idma(ap); |
| 366 | inic_stop_idma(ap); | ||
| 367 | 367 | ||
| 368 | /* Depending on circumstances, device error | 368 | /* Depending on circumstances, device error |
| 369 | * isn't reported by IDMA, check it explicitly. | 369 | * isn't reported by IDMA, check it explicitly. |
| 370 | */ | 370 | */ |
| 371 | if (unlikely(readb(port_base + PORT_TF_COMMAND) & | 371 | if (unlikely(readb(port_base + PORT_TF_COMMAND) & |
| 372 | (ATA_DF | ATA_ERR))) | 372 | (ATA_DF | ATA_ERR))) |
| 373 | qc->err_mask |= AC_ERR_DEV; | 373 | qc->err_mask |= AC_ERR_DEV; |
| 374 | 374 | ||
| 375 | ata_qc_complete(qc); | 375 | ata_qc_complete(qc); |
| 376 | return; | 376 | return; |
| 377 | } | ||
| 378 | } else { | ||
| 379 | if (likely(ata_sff_host_intr(ap, qc))) | ||
| 380 | return; | ||
| 381 | } | 377 | } |
| 382 | 378 | ||
| 383 | spurious: | 379 | spurious: |
| @@ -421,6 +417,19 @@ static irqreturn_t inic_interrupt(int irq, void *dev_instance) | |||
| 421 | return IRQ_RETVAL(handled); | 417 | return IRQ_RETVAL(handled); |
| 422 | } | 418 | } |
| 423 | 419 | ||
| 420 | static int inic_check_atapi_dma(struct ata_queued_cmd *qc) | ||
| 421 | { | ||
| 422 | /* For some reason ATAPI_PROT_DMA doesn't work for some | ||
| 423 | * commands including writes and other misc ops. Use PIO | ||
| 424 | * protocol instead, which BTW is driven by the DMA engine | ||
| 425 | * anyway, so it shouldn't make much difference for native | ||
| 426 | * SATA devices. | ||
| 427 | */ | ||
| 428 | if (atapi_cmd_type(qc->cdb[0]) == READ) | ||
| 429 | return 0; | ||
| 430 | return 1; | ||
| 431 | } | ||
| 432 | |||
| 424 | static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc) | 433 | static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc) |
| 425 | { | 434 | { |
| 426 | struct scatterlist *sg; | 435 | struct scatterlist *sg; |
| @@ -452,20 +461,21 @@ static void inic_qc_prep(struct ata_queued_cmd *qc) | |||
| 452 | struct inic_prd *prd = pkt->prd; | 461 | struct inic_prd *prd = pkt->prd; |
| 453 | bool is_atapi = ata_is_atapi(qc->tf.protocol); | 462 | bool is_atapi = ata_is_atapi(qc->tf.protocol); |
| 454 | bool is_data = ata_is_data(qc->tf.protocol); | 463 | bool is_data = ata_is_data(qc->tf.protocol); |
| 464 | unsigned int cdb_len = 0; | ||
| 455 | 465 | ||
| 456 | VPRINTK("ENTER\n"); | 466 | VPRINTK("ENTER\n"); |
| 457 | 467 | ||
| 458 | if (is_atapi) | 468 | if (is_atapi) |
| 459 | return; | 469 | cdb_len = qc->dev->cdb_len; |
| 460 | 470 | ||
| 461 | /* prepare packet, based on initio driver */ | 471 | /* prepare packet, based on initio driver */ |
| 462 | memset(pkt, 0, sizeof(struct inic_pkt)); | 472 | memset(pkt, 0, sizeof(struct inic_pkt)); |
| 463 | 473 | ||
| 464 | cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN; | 474 | cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN; |
| 465 | if (is_data) | 475 | if (is_atapi || is_data) |
| 466 | cpb->ctl_flags |= CPB_CTL_DATA; | 476 | cpb->ctl_flags |= CPB_CTL_DATA; |
| 467 | 477 | ||
| 468 | cpb->len = cpu_to_le32(qc->nbytes); | 478 | cpb->len = cpu_to_le32(qc->nbytes + cdb_len); |
| 469 | cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd)); | 479 | cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd)); |
| 470 | 480 | ||
| 471 | cpb->device = qc->tf.device; | 481 | cpb->device = qc->tf.device; |
| @@ -486,6 +496,18 @@ static void inic_qc_prep(struct ata_queued_cmd *qc) | |||
| 486 | cpb->command = qc->tf.command; | 496 | cpb->command = qc->tf.command; |
| 487 | /* don't load ctl - dunno why. it's like that in the initio driver */ | 497 | /* don't load ctl - dunno why. it's like that in the initio driver */ |
| 488 | 498 | ||
| 499 | /* setup PRD for CDB */ | ||
| 500 | if (is_atapi) { | ||
| 501 | memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN); | ||
| 502 | prd->mad = cpu_to_le32(pp->pkt_dma + | ||
| 503 | offsetof(struct inic_pkt, cdb)); | ||
| 504 | prd->len = cpu_to_le16(cdb_len); | ||
| 505 | prd->flags = PRD_CDB | PRD_WRITE; | ||
| 506 | if (!is_data) | ||
| 507 | prd->flags |= PRD_END; | ||
| 508 | prd++; | ||
| 509 | } | ||
| 510 | |||
| 489 | /* setup sg table */ | 511 | /* setup sg table */ |
| 490 | if (is_data) | 512 | if (is_data) |
| 491 | inic_fill_sg(prd, qc); | 513 | inic_fill_sg(prd, qc); |
| @@ -498,16 +520,12 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc) | |||
| 498 | struct ata_port *ap = qc->ap; | 520 | struct ata_port *ap = qc->ap; |
| 499 | void __iomem *port_base = inic_port_base(ap); | 521 | void __iomem *port_base = inic_port_base(ap); |
| 500 | 522 | ||
| 501 | if (!ata_is_atapi(qc->tf.protocol)) { | 523 | /* fire up the ADMA engine */ |
| 502 | /* fire up the ADMA engine */ | 524 | writew(HCTL_FTHD0, port_base + HOST_CTL); |
| 503 | writew(HCTL_FTHD0, port_base + HOST_CTL); | 525 | writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); |
| 504 | writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); | 526 | writeb(0, port_base + PORT_CPB_PTQFIFO); |
| 505 | writeb(0, port_base + PORT_CPB_PTQFIFO); | ||
| 506 | |||
| 507 | return 0; | ||
| 508 | } | ||
| 509 | 527 | ||
| 510 | return ata_sff_qc_issue(qc); | 528 | return 0; |
| 511 | } | 529 | } |
| 512 | 530 | ||
| 513 | static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | 531 | static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf) |
| @@ -698,6 +716,7 @@ static int inic_port_start(struct ata_port *ap) | |||
| 698 | static struct ata_port_operations inic_port_ops = { | 716 | static struct ata_port_operations inic_port_ops = { |
| 699 | .inherits = &ata_sff_port_ops, | 717 | .inherits = &ata_sff_port_ops, |
| 700 | 718 | ||
| 719 | .check_atapi_dma = inic_check_atapi_dma, | ||
| 701 | .qc_prep = inic_qc_prep, | 720 | .qc_prep = inic_qc_prep, |
| 702 | .qc_issue = inic_qc_issue, | 721 | .qc_issue = inic_qc_issue, |
| 703 | .qc_fill_rtf = inic_qc_fill_rtf, | 722 | .qc_fill_rtf = inic_qc_fill_rtf, |
| @@ -717,12 +736,6 @@ static struct ata_port_operations inic_port_ops = { | |||
| 717 | }; | 736 | }; |
| 718 | 737 | ||
| 719 | static struct ata_port_info inic_port_info = { | 738 | static struct ata_port_info inic_port_info = { |
| 720 | /* For some reason, ATAPI_PROT_PIO is broken on this | ||
| 721 | * controller, and no, PIO_POLLING does't fix it. It somehow | ||
| 722 | * manages to report the wrong ireason and ignoring ireason | ||
| 723 | * results in machine lock up. Tell libata to always prefer | ||
| 724 | * DMA. | ||
| 725 | */ | ||
| 726 | .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, | 739 | .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, |
| 727 | .pio_mask = 0x1f, /* pio0-4 */ | 740 | .pio_mask = 0x1f, /* pio0-4 */ |
| 728 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 741 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
