| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: siisata.c,v 1.2.4.3 2009/09/28 00:19:37 snj Exp $ */ | | 1 | /* $NetBSD: siisata.c,v 1.2.4.4 2009/09/28 00:21:13 snj Exp $ */ |
2 | | | 2 | |
3 | /* from ahcisata_core.c */ | | 3 | /* from ahcisata_core.c */ |
4 | | | 4 | |
5 | /* | | 5 | /* |
6 | * Copyright (c) 2006 Manuel Bouyer. | | 6 | * Copyright (c) 2006 Manuel Bouyer. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -484,106 +484,94 @@ siisata_intr_port(struct siisata_channel | | | @@ -484,106 +484,94 @@ siisata_intr_port(struct siisata_channel |
484 | prbfis = bus_space_read_stream_4( | | 484 | prbfis = bus_space_read_stream_4( |
485 | sc->sc_prt, sc->sc_prh, | | 485 | sc->sc_prt, sc->sc_prh, |
486 | PRSX(chp->ch_channel, slot, PRSO_FIS)); | | 486 | PRSX(chp->ch_channel, slot, PRSO_FIS)); |
487 | /* set ch_status and ch_error */ | | 487 | /* set ch_status and ch_error */ |
488 | satafis_sdb_parse(chp, (uint8_t *)&prbfis); | | 488 | satafis_sdb_parse(chp, (uint8_t *)&prbfis); |
489 | } | | 489 | } |
490 | siisata_reinit_port(chp); | | 490 | siisata_reinit_port(chp); |
491 | } else { | | 491 | } else { |
492 | /* okay, we have a "Fatal Error" */ | | 492 | /* okay, we have a "Fatal Error" */ |
493 | siisata_device_reset(chp); | | 493 | siisata_device_reset(chp); |
494 | } | | 494 | } |
495 | } | | 495 | } |
496 | | | 496 | |
| | | 497 | /* clear some (ok, all) ints */ |
| | | 498 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); |
| | | 499 | |
497 | KASSERT(xfer != NULL); | | 500 | KASSERT(xfer != NULL); |
498 | KASSERT(xfer->c_intr != NULL); | | 501 | KASSERT(xfer->c_intr != NULL); |
499 | xfer->c_intr(chp, xfer, slot); | | 502 | xfer->c_intr(chp, xfer, slot); |
500 | | | 503 | |
501 | /* clear some (ok, all) ints */ | | | |
502 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); | | | |
503 | | | | |
504 | return; | | 504 | return; |
505 | } | | 505 | } |
506 | | | 506 | |
507 | void | | 507 | void |
508 | siisata_reset_drive(struct ata_drive_datas *drvp, int flags) | | 508 | siisata_reset_drive(struct ata_drive_datas *drvp, int flags) |
509 | { | | 509 | { |
510 | struct ata_channel *chp = drvp->chnl_softc; | | 510 | struct ata_channel *chp = drvp->chnl_softc; |
511 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 511 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
512 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 512 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
513 | struct siisata_prb *prb; | | 513 | struct siisata_prb *prb; |
514 | kmutex_t mtx; | | | |
515 | kcondvar_t cv; | | | |
516 | int slot = SIISATA_NON_NCQ_SLOT; | | 514 | int slot = SIISATA_NON_NCQ_SLOT; |
517 | int i; | | 515 | int i; |
518 | int wait; | | | |
519 | | | | |
520 | mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE); | | | |
521 | cv_init(&cv, "siipd"); | | | |
522 | | | | |
523 | wait = mstohz(10); | | | |
524 | wait = wait ? wait : 1; | | | |
525 | | | 516 | |
526 | /* wait for ready */ | | 517 | /* wait for ready */ |
527 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) | | 518 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) |
528 | DELAY(10); | | 519 | DELAY(10); |
529 | | | 520 | |
530 | prb = schp->sch_prb[slot]; | | 521 | prb = schp->sch_prb[slot]; |
531 | memset(prb, 0, sizeof(struct siisata_prb)); | | 522 | memset(prb, 0, sizeof(struct siisata_prb)); |
532 | prb->prb_control = | | 523 | prb->prb_control = |
533 | htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK); | | 524 | htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK); |
534 | | | 525 | |
535 | siisata_activate_prb(schp, slot); | | 526 | siisata_activate_prb(schp, slot); |
536 | | | 527 | |
537 | for(i = 0; i < (31000/(1000/(wait*hz))); i++) { | | 528 | for(i = 0; i < 31000; i++) { |
538 | if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & | | 529 | if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & |
539 | PR_PXSS(slot)) | | 530 | PR_PXSS(slot)) |
540 | break; | | 531 | DELAY(1000); |
541 | else | | 532 | else |
542 | cv_timedwait(&cv, &mtx, wait); | | 533 | break; |
543 | } | | 534 | } |
544 | | | 535 | |
545 | siisata_deactivate_prb(schp, slot); | | 536 | siisata_deactivate_prb(schp, slot); |
546 | | | 537 | |
547 | log(LOG_DEBUG, "%s: ch_status %x ch_error %x\n", | | 538 | log(LOG_DEBUG, "%s: port %d: ch_status %x ch_error %x\n", |
548 | __func__, chp->ch_status, chp->ch_error); | | 539 | __func__, chp->ch_channel, chp->ch_status, chp->ch_error); |
549 | | | 540 | |
550 | #if 1 | | 541 | #if 1 |
551 | /* attempt to downgrade signaling in event of CRC error */ | | 542 | /* attempt to downgrade signaling in event of CRC error */ |
552 | /* XXX should be part of the MI (S)ATA subsystem */ | | 543 | /* XXX should be part of the MI (S)ATA subsystem */ |
553 | if (chp->ch_status == 0x51 && chp->ch_error == 0x84) { | | 544 | if (chp->ch_status == 0x51 && chp->ch_error == 0x84) { |
554 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, | | 545 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, |
555 | SControl_IPM_NONE | SControl_SPD_G1 | SControl_DET_INIT); | | 546 | SControl_IPM_NONE | SControl_SPD_G1 | SControl_DET_INIT); |
556 | DELAY(10); | | 547 | DELAY(10); |
557 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, | | 548 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, |
558 | SControl_IPM_NONE | SControl_SPD_G1); | | 549 | SControl_IPM_NONE | SControl_SPD_G1); |
559 | DELAY(10); | | 550 | DELAY(10); |
560 | for (;;) { | | 551 | for (;;) { |
561 | if ((bus_space_read_4(sc->sc_prt, schp->sch_sstatus, 0) | | 552 | if ((bus_space_read_4(sc->sc_prt, schp->sch_sstatus, 0) |
562 | & SStatus_DET_mask) == SStatus_DET_DEV) | | 553 | & SStatus_DET_mask) == SStatus_DET_DEV) |
563 | break; | | 554 | break; |
564 | DELAY(10); | | 555 | DELAY(10); |
565 | } | | 556 | } |
566 | } | | 557 | } |
567 | #endif | | 558 | #endif |
568 | | | 559 | |
569 | #if 1 | | 560 | #if 1 |
570 | chp->ch_status = 0; | | 561 | chp->ch_status = 0; |
571 | chp->ch_error = 0; | | 562 | chp->ch_error = 0; |
572 | #endif | | 563 | #endif |
573 | | | 564 | |
574 | cv_destroy(&cv); | | | |
575 | mutex_destroy(&mtx); | | | |
576 | | | | |
577 | return; | | 565 | return; |
578 | } | | 566 | } |
579 | | | 567 | |
580 | void | | 568 | void |
581 | siisata_reset_channel(struct ata_channel *chp, int flags) | | 569 | siisata_reset_channel(struct ata_channel *chp, int flags) |
582 | { | | 570 | { |
583 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 571 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
584 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 572 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
585 | | | 573 | |
586 | SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__), | | 574 | SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__), |
587 | DEBUG_FUNCS); | | 575 | DEBUG_FUNCS); |
588 | | | 576 | |
589 | if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, | | 577 | if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, |
| @@ -623,66 +611,57 @@ siisata_killpending(struct ata_drive_dat | | | @@ -623,66 +611,57 @@ siisata_killpending(struct ata_drive_dat |
623 | return; | | 611 | return; |
624 | } | | 612 | } |
625 | | | 613 | |
626 | void | | 614 | void |
627 | siisata_probe_drive(struct ata_channel *chp) | | 615 | siisata_probe_drive(struct ata_channel *chp) |
628 | { | | 616 | { |
629 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 617 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
630 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 618 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
631 | int i; | | 619 | int i; |
632 | int s; | | 620 | int s; |
633 | uint32_t sig; | | 621 | uint32_t sig; |
634 | int slot = SIISATA_NON_NCQ_SLOT; | | 622 | int slot = SIISATA_NON_NCQ_SLOT; |
635 | struct siisata_prb *prb; | | 623 | struct siisata_prb *prb; |
636 | kmutex_t mtx; | | | |
637 | kcondvar_t cv; | | | |
638 | int wait; | | | |
639 | | | 624 | |
640 | SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc), | | 625 | SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc), |
641 | __func__, chp->ch_channel), DEBUG_FUNCS); | | 626 | __func__, chp->ch_channel), DEBUG_FUNCS); |
642 | | | 627 | |
643 | /* XXX This should be done by other code. */ | | 628 | /* XXX This should be done by other code. */ |
644 | for (i = 0; i < chp->ch_ndrive; i++) { | | 629 | for (i = 0; i < chp->ch_ndrive; i++) { |
645 | chp->ch_drive[i].chnl_softc = chp; | | 630 | chp->ch_drive[i].chnl_softc = chp; |
646 | chp->ch_drive[i].drive = i; | | 631 | chp->ch_drive[i].drive = i; |
647 | } | | 632 | } |
648 | | | 633 | |
649 | mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE); | | | |
650 | cv_init(&cv, "siipd"); | | | |
651 | | | | |
652 | wait = mstohz(10); | | | |
653 | wait = wait ? wait : 1; | | | |
654 | | | | |
655 | switch (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, | | 634 | switch (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, |
656 | schp->sch_sstatus)) { | | 635 | schp->sch_sstatus)) { |
657 | case SStatus_DET_DEV: | | 636 | case SStatus_DET_DEV: |
658 | /* wait for ready */ | | 637 | /* wait for ready */ |
659 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) | | 638 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) |
660 | & PR_PS_PORT_READY)) | | 639 | & PR_PS_PORT_READY)) |
661 | DELAY(10); | | 640 | DELAY(10); |
662 | | | 641 | |
663 | prb = schp->sch_prb[slot]; | | 642 | prb = schp->sch_prb[slot]; |
664 | memset(prb, 0, sizeof(struct siisata_prb)); | | 643 | memset(prb, 0, sizeof(struct siisata_prb)); |
665 | prb->prb_control = | | 644 | prb->prb_control = |
666 | htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK); | | 645 | htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK); |
667 | | | 646 | |
668 | siisata_activate_prb(schp, slot); | | 647 | siisata_activate_prb(schp, slot); |
669 | | | 648 | |
670 | for(i = 0; i < (31000/(1000/(wait*hz))); i++) { | | 649 | for(i = 0; i < 31000; i++) { |
671 | if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & | | 650 | if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & |
672 | PR_PXSS(slot)) | | 651 | PR_PXSS(slot)) |
673 | break; | | 652 | DELAY(1000); |
674 | else | | 653 | else |
675 | cv_timedwait(&cv, &mtx, wait); | | 654 | break; |
676 | } | | 655 | } |
677 | | | 656 | |
678 | siisata_deactivate_prb(schp, slot); | | 657 | siisata_deactivate_prb(schp, slot); |
679 | | | 658 | |
680 | /* read the signature out of the FIS */ | | 659 | /* read the signature out of the FIS */ |
681 | sig = 0; | | 660 | sig = 0; |
682 | sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot, | | 661 | sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot, |
683 | PRSO_FIS+0x4)) & 0x00ffffff) << 8; | | 662 | PRSO_FIS+0x4)) & 0x00ffffff) << 8; |
684 | sig |= PRREAD(sc, PRSX(chp->ch_channel, slot, | | 663 | sig |= PRREAD(sc, PRSX(chp->ch_channel, slot, |
685 | PRSO_FIS+0xc)) & 0xff; | | 664 | PRSO_FIS+0xc)) & 0xff; |
686 | | | 665 | |
687 | SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc), | | 666 | SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc), |
688 | __func__, sig), DEBUG_PROBE); | | 667 | __func__, sig), DEBUG_PROBE); |
| @@ -704,29 +683,26 @@ siisata_probe_drive(struct ata_channel * | | | @@ -704,29 +683,26 @@ siisata_probe_drive(struct ata_channel * |
704 | default: | | 683 | default: |
705 | chp->ch_drive[0].drive_flags |= DRIVE_ATA; | | 684 | chp->ch_drive[0].drive_flags |= DRIVE_ATA; |
706 | aprint_verbose_dev(sc->sc_atac.atac_dev, | | 685 | aprint_verbose_dev(sc->sc_atac.atac_dev, |
707 | "Unrecognized signature 0x%08x on port %d. " | | 686 | "Unrecognized signature 0x%08x on port %d. " |
708 | "Assuming it's a disk.\n", sig, chp->ch_channel); | | 687 | "Assuming it's a disk.\n", sig, chp->ch_channel); |
709 | break; | | 688 | break; |
710 | } | | 689 | } |
711 | splx(s); | | 690 | splx(s); |
712 | break; | | 691 | break; |
713 | default: | | 692 | default: |
714 | break; | | 693 | break; |
715 | } | | 694 | } |
716 | | | 695 | |
717 | cv_destroy(&cv); | | | |
718 | mutex_destroy(&mtx); | | | |
719 | | | | |
720 | SIISATA_DEBUG_PRINT(("%s: %s: port %d done\n", SIISATANAME(sc), | | 696 | SIISATA_DEBUG_PRINT(("%s: %s: port %d done\n", SIISATANAME(sc), |
721 | __func__, chp->ch_channel), DEBUG_PROBE); | | 697 | __func__, chp->ch_channel), DEBUG_PROBE); |
722 | return; | | 698 | return; |
723 | } | | 699 | } |
724 | | | 700 | |
725 | void | | 701 | void |
726 | siisata_setup_channel(struct ata_channel *chp) | | 702 | siisata_setup_channel(struct ata_channel *chp) |
727 | { | | 703 | { |
728 | return; | | 704 | return; |
729 | } | | 705 | } |
730 | | | 706 | |
731 | int | | 707 | int |
732 | siisata_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c) | | 708 | siisata_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c) |
| @@ -826,27 +802,27 @@ siisata_cmd_start(struct ata_channel *ch | | | @@ -826,27 +802,27 @@ siisata_cmd_start(struct ata_channel *ch |
826 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ | | 802 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ |
827 | callout_reset(&chp->ch_callout, mstohz(ata_c->timeout), | | 803 | callout_reset(&chp->ch_callout, mstohz(ata_c->timeout), |
828 | siisata_timeout, chp); | | 804 | siisata_timeout, chp); |
829 | goto out; | | 805 | goto out; |
830 | } | | 806 | } |
831 | | | 807 | |
832 | /* | | 808 | /* |
833 | * polled command | | 809 | * polled command |
834 | */ | | 810 | */ |
835 | for (i = 0; i < ata_c->timeout / 10; i++) { | | 811 | for (i = 0; i < ata_c->timeout / 10; i++) { |
836 | if (ata_c->flags & AT_DONE) | | 812 | if (ata_c->flags & AT_DONE) |
837 | break; | | 813 | break; |
838 | siisata_intr_port(schp); | | 814 | siisata_intr_port(schp); |
839 | DELAY(10000); | | 815 | DELAY(1000); |
840 | } | | 816 | } |
841 | | | 817 | |
842 | if ((ata_c->flags & AT_DONE) == 0) { | | 818 | if ((ata_c->flags & AT_DONE) == 0) { |
843 | ata_c->flags |= AT_TIMEOU; | | 819 | ata_c->flags |= AT_TIMEOU; |
844 | siisata_cmd_complete(chp, xfer, slot); | | 820 | siisata_cmd_complete(chp, xfer, slot); |
845 | } | | 821 | } |
846 | | | 822 | |
847 | /* reenable interrupts */ | | 823 | /* reenable interrupts */ |
848 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); | | 824 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); |
849 | out: | | 825 | out: |
850 | SIISATA_DEBUG_PRINT( | | 826 | SIISATA_DEBUG_PRINT( |
851 | ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); | | 827 | ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); |
852 | return; | | 828 | return; |
| @@ -1028,27 +1004,27 @@ siisata_bio_start(struct ata_channel *ch | | | @@ -1028,27 +1004,27 @@ siisata_bio_start(struct ata_channel *ch |
1028 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ | | 1004 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ |
1029 | callout_reset(&chp->ch_callout, mstohz(ATA_DELAY), | | 1005 | callout_reset(&chp->ch_callout, mstohz(ATA_DELAY), |
1030 | siisata_timeout, chp); | | 1006 | siisata_timeout, chp); |
1031 | goto out; | | 1007 | goto out; |
1032 | } | | 1008 | } |
1033 | | | 1009 | |
1034 | /* | | 1010 | /* |
1035 | * polled command | | 1011 | * polled command |
1036 | */ | | 1012 | */ |
1037 | for (i = 0; i < ATA_DELAY / 10; i++) { | | 1013 | for (i = 0; i < ATA_DELAY / 10; i++) { |
1038 | if (ata_bio->flags & ATA_ITSDONE) | | 1014 | if (ata_bio->flags & ATA_ITSDONE) |
1039 | break; | | 1015 | break; |
1040 | siisata_intr_port(schp); | | 1016 | siisata_intr_port(schp); |
1041 | DELAY(10000); | | 1017 | DELAY(1000); |
1042 | } | | 1018 | } |
1043 | | | 1019 | |
1044 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); | | 1020 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); |
1045 | out: | | 1021 | out: |
1046 | SIISATA_DEBUG_PRINT( | | 1022 | SIISATA_DEBUG_PRINT( |
1047 | ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); | | 1023 | ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); |
1048 | return; | | 1024 | return; |
1049 | } | | 1025 | } |
1050 | | | 1026 | |
1051 | void | | 1027 | void |
1052 | siisata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, | | 1028 | siisata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, |
1053 | int reason) | | 1029 | int reason) |
1054 | { | | 1030 | { |
| @@ -1113,29 +1089,33 @@ siisata_bio_complete(struct ata_channel | | | @@ -1113,29 +1089,33 @@ siisata_bio_complete(struct ata_channel |
1113 | } | | 1089 | } |
1114 | ata_free_xfer(chp, xfer); | | 1090 | ata_free_xfer(chp, xfer); |
1115 | ata_bio->flags |= ATA_ITSDONE; | | 1091 | ata_bio->flags |= ATA_ITSDONE; |
1116 | if (chp->ch_status & WDCS_DWF) { | | 1092 | if (chp->ch_status & WDCS_DWF) { |
1117 | ata_bio->error = ERR_DF; | | 1093 | ata_bio->error = ERR_DF; |
1118 | } else if (chp->ch_status & WDCS_ERR) { | | 1094 | } else if (chp->ch_status & WDCS_ERR) { |
1119 | ata_bio->error = ERROR; | | 1095 | ata_bio->error = ERROR; |
1120 | ata_bio->r_error = chp->ch_error; | | 1096 | ata_bio->r_error = chp->ch_error; |
1121 | } else if (chp->ch_status & WDCS_CORR) | | 1097 | } else if (chp->ch_status & WDCS_CORR) |
1122 | ata_bio->flags |= ATA_CORR; | | 1098 | ata_bio->flags |= ATA_CORR; |
1123 | | | 1099 | |
1124 | SIISATA_DEBUG_PRINT(("%s: %s bcount: %ld", SIISATANAME(sc), | | 1100 | SIISATA_DEBUG_PRINT(("%s: %s bcount: %ld", SIISATANAME(sc), |
1125 | __func__, ata_bio->bcount), DEBUG_XFERS); | | 1101 | __func__, ata_bio->bcount), DEBUG_XFERS); |
1126 | if ((ata_bio->flags & ATA_READ) || (ata_bio->error == NOERROR)) | | 1102 | if (ata_bio->error == NOERROR) { |
1127 | ata_bio->bcount -= PRREAD(sc, | | 1103 | if (ata_bio->flags & ATA_READ) |
1128 | PRSX(chp->ch_channel, slot, PRSO_RTC)); | | 1104 | ata_bio->bcount -= |
| | | 1105 | PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC)); |
| | | 1106 | else |
| | | 1107 | ata_bio->bcount = 0; |
| | | 1108 | } |
1129 | SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); | | 1109 | SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); |
1130 | if (ata_bio->flags & ATA_POLL) | | 1110 | if (ata_bio->flags & ATA_POLL) |
1131 | return 1; | | 1111 | return 1; |
1132 | (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc); | | 1112 | (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc); |
1133 | atastart(chp); | | 1113 | atastart(chp); |
1134 | return 0; | | 1114 | return 0; |
1135 | } | | 1115 | } |
1136 | | | 1116 | |
1137 | void | | 1117 | void |
1138 | siisata_timeout(void *v) | | 1118 | siisata_timeout(void *v) |
1139 | { | | 1119 | { |
1140 | struct ata_channel *chp = (struct ata_channel *)v; | | 1120 | struct ata_channel *chp = (struct ata_channel *)v; |
1141 | struct ata_xfer *xfer = chp->ch_queue->active_xfer; | | 1121 | struct ata_xfer *xfer = chp->ch_queue->active_xfer; |
| @@ -1193,54 +1173,43 @@ siisata_dma_setup(struct ata_channel *ch | | | @@ -1193,54 +1173,43 @@ siisata_dma_setup(struct ata_channel *ch |
1193 | htole32(schp->sch_datad[slot]->dm_segs[seg].ds_len); | | 1173 | htole32(schp->sch_datad[slot]->dm_segs[seg].ds_len); |
1194 | prbp->prb_sge[seg].sge_flags = htole32(0); | | 1174 | prbp->prb_sge[seg].sge_flags = htole32(0); |
1195 | } | | 1175 | } |
1196 | prbp->prb_sge[seg - 1].sge_flags |= htole32(SGE_FLAG_TRM); | | 1176 | prbp->prb_sge[seg - 1].sge_flags |= htole32(SGE_FLAG_TRM); |
1197 | end: | | 1177 | end: |
1198 | return 0; | | 1178 | return 0; |
1199 | } | | 1179 | } |
1200 | | | 1180 | |
1201 | static void | | 1181 | static void |
1202 | siisata_activate_prb(struct siisata_channel *schp, int slot) | | 1182 | siisata_activate_prb(struct siisata_channel *schp, int slot) |
1203 | { | | 1183 | { |
1204 | struct siisata_softc *sc; | | 1184 | struct siisata_softc *sc; |
1205 | bus_size_t offset; | | 1185 | bus_size_t offset; |
1206 | bus_addr_t pprb; | | 1186 | uint64_t pprb; |
1207 | int port; | | | |
1208 | | | 1187 | |
1209 | sc = (struct siisata_softc *)schp->ata_channel.ch_atac; | | 1188 | sc = (struct siisata_softc *)schp->ata_channel.ch_atac; |
1210 | | | 1189 | |
1211 | KASSERTMSG(((schp->sch_active_slots & __BIT(slot)) == __BIT(slot)), | | 1190 | KASSERTMSG(((schp->sch_active_slots & __BIT(slot)) == __BIT(slot)), |
1212 | ("%s: trying to activate active slot %d", SIISATANAME(sc), slot)); | | 1191 | ("%s: trying to activate active slot %d", SIISATANAME(sc), slot)); |
1213 | | | 1192 | |
1214 | port = schp->ata_channel.ch_channel; | | | |
1215 | | | | |
1216 | offset = PRO_CARX(port, slot); | | | |
1217 | | | | |
1218 | pprb = schp->sch_bus_prb[slot]; | | | |
1219 | | | | |
1220 | | | | |
1221 | SIISATA_PRB_SYNC(sc, schp, slot, BUS_DMASYNC_PREWRITE); | | 1193 | SIISATA_PRB_SYNC(sc, schp, slot, BUS_DMASYNC_PREWRITE); |
1222 | /* keep track of what's going on */ | | 1194 | /* keep track of what's going on */ |
1223 | schp->sch_active_slots |= __BIT(slot); | | 1195 | schp->sch_active_slots |= __BIT(slot); |
1224 | | | 1196 | |
| | | 1197 | offset = PRO_CARX(schp->ata_channel.ch_channel, slot); |
1225 | | | 1198 | |
1226 | PRWRITE(sc, offset, pprb); | | 1199 | pprb = schp->sch_bus_prb[slot]; |
1227 | offset += 4; | | 1200 | |
1228 | #if 0 | | 1201 | PRWRITE(sc, offset + 0, pprb >> 0); |
1229 | if (sizeof(bus_addr_t) == 8) | | 1202 | PRWRITE(sc, offset + 4, pprb >> 32); |
1230 | PRWRITE(sc, offset, (pprb >> 32)); | | | |
1231 | else | | | |
1232 | #endif | | | |
1233 | PRWRITE(sc, offset, 0); | | | |
1234 | } | | 1203 | } |
1235 | | | 1204 | |
1236 | static void | | 1205 | static void |
1237 | siisata_deactivate_prb(struct siisata_channel *schp, int slot) | | 1206 | siisata_deactivate_prb(struct siisata_channel *schp, int slot) |
1238 | { | | 1207 | { |
1239 | struct siisata_softc *sc; | | 1208 | struct siisata_softc *sc; |
1240 | | | 1209 | |
1241 | sc = (struct siisata_softc *)schp->ata_channel.ch_atac; | | 1210 | sc = (struct siisata_softc *)schp->ata_channel.ch_atac; |
1242 | | | 1211 | |
1243 | KASSERTMSG(((schp->sch_active_slots & __BIT(slot)) == 0), | | 1212 | KASSERTMSG(((schp->sch_active_slots & __BIT(slot)) == 0), |
1244 | ("%s: trying to deactivate inactive slot %d", SIISATANAME(sc), | | 1213 | ("%s: trying to deactivate inactive slot %d", SIISATANAME(sc), |
1245 | slot)); | | 1214 | slot)); |
1246 | | | 1215 | |
| @@ -1369,27 +1338,27 @@ siisata_atapi_probe_device(struct atapib | | | @@ -1369,27 +1338,27 @@ siisata_atapi_probe_device(struct atapib |
1369 | | | 1338 | |
1370 | /* skip if already attached */ | | 1339 | /* skip if already attached */ |
1371 | if (scsipi_lookup_periph(chan, target, 0) != NULL) | | 1340 | if (scsipi_lookup_periph(chan, target, 0) != NULL) |
1372 | return; | | 1341 | return; |
1373 | | | 1342 | |
1374 | /* if no ATAPI device detected at attach time, skip */ | | 1343 | /* if no ATAPI device detected at attach time, skip */ |
1375 | if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { | | 1344 | if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { |
1376 | SIISATA_DEBUG_PRINT(("%s: drive %d " | | 1345 | SIISATA_DEBUG_PRINT(("%s: drive %d " |
1377 | "not present\n", __func__, target), DEBUG_PROBE); | | 1346 | "not present\n", __func__, target), DEBUG_PROBE); |
1378 | return; | | 1347 | return; |
1379 | } | | 1348 | } |
1380 | | | 1349 | |
1381 | /* Some ATAPI devices need a bit more time after software reset. */ | | 1350 | /* Some ATAPI devices need a bit more time after software reset. */ |
1382 | delay(5000); | | 1351 | DELAY(5000); |
1383 | if (ata_get_params(drvp, AT_WAIT, id) == 0) { | | 1352 | if (ata_get_params(drvp, AT_WAIT, id) == 0) { |
1384 | #ifdef ATAPI_DEBUG_PROBE | | 1353 | #ifdef ATAPI_DEBUG_PROBE |
1385 | log(LOG_DEBUG, "%s drive %d: cmdsz 0x%x drqtype 0x%x\n", | | 1354 | log(LOG_DEBUG, "%s drive %d: cmdsz 0x%x drqtype 0x%x\n", |
1386 | device_xname(sc->sc_dev), target, | | 1355 | device_xname(sc->sc_dev), target, |
1387 | id->atap_config & ATAPI_CFG_CMD_MASK, | | 1356 | id->atap_config & ATAPI_CFG_CMD_MASK, |
1388 | id->atap_config & ATAPI_CFG_DRQ_MASK); | | 1357 | id->atap_config & ATAPI_CFG_DRQ_MASK); |
1389 | #endif | | 1358 | #endif |
1390 | periph = scsipi_alloc_periph(M_NOWAIT); | | 1359 | periph = scsipi_alloc_periph(M_NOWAIT); |
1391 | if (periph == NULL) { | | 1360 | if (periph == NULL) { |
1392 | aprint_error_dev(sc->sc_dev, | | 1361 | aprint_error_dev(sc->sc_dev, |
1393 | "%s: unable to allocate periph for " | | 1362 | "%s: unable to allocate periph for " |
1394 | "channel %d drive %d\n", __func__, | | 1363 | "channel %d drive %d\n", __func__, |
1395 | chp->ch_channel, target); | | 1364 | chp->ch_channel, target); |
| @@ -1581,27 +1550,27 @@ siisata_atapi_start(struct ata_channel * | | | @@ -1581,27 +1550,27 @@ siisata_atapi_start(struct ata_channel * |
1581 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ | | 1550 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ |
1582 | callout_reset(&chp->ch_callout, mstohz(sc_xfer->timeout), | | 1551 | callout_reset(&chp->ch_callout, mstohz(sc_xfer->timeout), |
1583 | siisata_timeout, chp); | | 1552 | siisata_timeout, chp); |
1584 | goto out; | | 1553 | goto out; |
1585 | } | | 1554 | } |
1586 | | | 1555 | |
1587 | /* | | 1556 | /* |
1588 | * polled command | | 1557 | * polled command |
1589 | */ | | 1558 | */ |
1590 | for (i = 0; i < ATA_DELAY / 10; i++) { | | 1559 | for (i = 0; i < ATA_DELAY / 10; i++) { |
1591 | if (sc_xfer->xs_status & XS_STS_DONE) | | 1560 | if (sc_xfer->xs_status & XS_STS_DONE) |
1592 | break; | | 1561 | break; |
1593 | siisata_intr_port(schp); | | 1562 | siisata_intr_port(schp); |
1594 | DELAY(10000); | | 1563 | DELAY(1000); |
1595 | } | | 1564 | } |
1596 | if ((sc_xfer->xs_status & XS_STS_DONE) == 0) { | | 1565 | if ((sc_xfer->xs_status & XS_STS_DONE) == 0) { |
1597 | sc_xfer->error = XS_TIMEOUT; | | 1566 | sc_xfer->error = XS_TIMEOUT; |
1598 | siisata_atapi_complete(chp, xfer, slot); | | 1567 | siisata_atapi_complete(chp, xfer, slot); |
1599 | } | | 1568 | } |
1600 | /* reenable interrupts */ | | 1569 | /* reenable interrupts */ |
1601 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); | | 1570 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); |
1602 | out: | | 1571 | out: |
1603 | SIISATA_DEBUG_PRINT( | | 1572 | SIISATA_DEBUG_PRINT( |
1604 | ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); | | 1573 | ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); |
1605 | return; | | 1574 | return; |
1606 | } | | 1575 | } |
1607 | | | 1576 | |