ncr53c9x.c (226381) | ncr53c9x.c (226947) |
---|---|
1/*- 2 * Copyright (c) 2004 Scott Long 3 * Copyright (c) 2005, 2008 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 84 unchanged lines hidden (view full) --- 93 * Based on aic6360 by Jarle Greipsland 94 * 95 * Acknowledgements: Many of the algorithms used in this driver are 96 * inspired by the work of Julian Elischer (julian@FreeBSD.org) and 97 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million! 98 */ 99 100#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004 Scott Long 3 * Copyright (c) 2005, 2008 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 84 unchanged lines hidden (view full) --- 93 * Based on aic6360 by Jarle Greipsland 94 * 95 * Acknowledgements: Many of the algorithms used in this driver are 96 * inspired by the work of Julian Elischer (julian@FreeBSD.org) and 97 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million! 98 */ 99 100#include <sys/cdefs.h> |
101__FBSDID("$FreeBSD: head/sys/dev/esp/ncr53c9x.c 226381 2011-10-15 09:29:43Z marius $"); | 101__FBSDID("$FreeBSD: head/sys/dev/esp/ncr53c9x.c 226947 2011-10-30 21:17:42Z marius $"); |
102 103#include <sys/param.h> 104#include <sys/systm.h> 105#include <sys/bus.h> 106#include <sys/kernel.h> 107#include <sys/malloc.h> 108#include <sys/lock.h> 109#include <sys/module.h> --- 8 unchanged lines hidden (view full) --- 118#include <cam/cam_sim.h> 119#include <cam/cam_xpt_sim.h> 120#include <cam/scsi/scsi_all.h> 121#include <cam/scsi/scsi_message.h> 122 123#include <dev/esp/ncr53c9xreg.h> 124#include <dev/esp/ncr53c9xvar.h> 125 | 102 103#include <sys/param.h> 104#include <sys/systm.h> 105#include <sys/bus.h> 106#include <sys/kernel.h> 107#include <sys/malloc.h> 108#include <sys/lock.h> 109#include <sys/module.h> --- 8 unchanged lines hidden (view full) --- 118#include <cam/cam_sim.h> 119#include <cam/cam_xpt_sim.h> 120#include <cam/scsi/scsi_all.h> 121#include <cam/scsi/scsi_message.h> 122 123#include <dev/esp/ncr53c9xreg.h> 124#include <dev/esp/ncr53c9xvar.h> 125 |
126devclass_t esp_devclass; 127 |
|
126MODULE_DEPEND(esp, cam, 1, 1, 1); 127 128#ifdef NCR53C9X_DEBUG 129int ncr53c9x_debug = 130 NCR_SHOWMISC /* | NCR_SHOWPHASE | NCR_SHOWTRAC | NCR_SHOWCMDS */; 131#endif 132 133static void ncr53c9x_abort(struct ncr53c9x_softc *sc, --- 40 unchanged lines hidden (view full) --- 174 int period); 175 176#define NCR_RDFIFO_START 0 177#define NCR_RDFIFO_CONTINUE 1 178 179#define NCR_SET_COUNT(sc, size) do { \ 180 NCR_WRITE_REG((sc), NCR_TCL, (size)); \ 181 NCR_WRITE_REG((sc), NCR_TCM, (size) >> 8); \ | 128MODULE_DEPEND(esp, cam, 1, 1, 1); 129 130#ifdef NCR53C9X_DEBUG 131int ncr53c9x_debug = 132 NCR_SHOWMISC /* | NCR_SHOWPHASE | NCR_SHOWTRAC | NCR_SHOWCMDS */; 133#endif 134 135static void ncr53c9x_abort(struct ncr53c9x_softc *sc, --- 40 unchanged lines hidden (view full) --- 176 int period); 177 178#define NCR_RDFIFO_START 0 179#define NCR_RDFIFO_CONTINUE 1 180 181#define NCR_SET_COUNT(sc, size) do { \ 182 NCR_WRITE_REG((sc), NCR_TCL, (size)); \ 183 NCR_WRITE_REG((sc), NCR_TCM, (size) >> 8); \ |
182 if ((sc->sc_cfg2 & NCRCFG2_FE) || \ 183 (sc->sc_rev == NCR_VARIANT_FAS366)) \ | 184 if ((sc->sc_features & NCR_F_LARGEXFER) != 0) \ |
184 NCR_WRITE_REG((sc), NCR_TCH, (size) >> 16); \ 185 if (sc->sc_rev == NCR_VARIANT_FAS366) \ 186 NCR_WRITE_REG(sc, NCR_RCH, 0); \ 187} while (/* CONSTCOND */0) 188 189#ifndef mstohz 190#define mstohz(ms) \ 191 (((ms) < 0x20000) ? \ --- 194 unchanged lines hidden (view full) --- 386 device_printf(sc->sc_dev, "cannot allocate ECB array\n"); 387 error = ENOMEM; 388 goto fail_async; 389 } 390 for (i = 0; i < NCR_TAG_DEPTH; i++) { 391 ecb = &sc->ecb_array[i]; 392 ecb->sc = sc; 393 ecb->tag_id = i; | 185 NCR_WRITE_REG((sc), NCR_TCH, (size) >> 16); \ 186 if (sc->sc_rev == NCR_VARIANT_FAS366) \ 187 NCR_WRITE_REG(sc, NCR_RCH, 0); \ 188} while (/* CONSTCOND */0) 189 190#ifndef mstohz 191#define mstohz(ms) \ 192 (((ms) < 0x20000) ? \ --- 194 unchanged lines hidden (view full) --- 387 device_printf(sc->sc_dev, "cannot allocate ECB array\n"); 388 error = ENOMEM; 389 goto fail_async; 390 } 391 for (i = 0; i < NCR_TAG_DEPTH; i++) { 392 ecb = &sc->ecb_array[i]; 393 ecb->sc = sc; 394 ecb->tag_id = i; |
395 callout_init_mtx(&ecb->ch, &sc->sc_lock, 0); |
|
394 TAILQ_INSERT_HEAD(&sc->free_list, ecb, free_links); 395 } 396 397 callout_reset(&sc->sc_watchdog, 60 * hz, ncr53c9x_watch, sc); 398 399 NCR_UNLOCK(sc); 400 401 return (0); --- 42 unchanged lines hidden (view full) --- 444 free(li, M_DEVBUF); 445 } 446 } 447 } 448 449 xpt_register_async(0, ncr53c9x_async, sc->sc_sim, sc->sc_path); 450 xpt_free_path(sc->sc_path); 451 xpt_bus_deregister(cam_sim_path(sc->sc_sim)); | 396 TAILQ_INSERT_HEAD(&sc->free_list, ecb, free_links); 397 } 398 399 callout_reset(&sc->sc_watchdog, 60 * hz, ncr53c9x_watch, sc); 400 401 NCR_UNLOCK(sc); 402 403 return (0); --- 42 unchanged lines hidden (view full) --- 446 free(li, M_DEVBUF); 447 } 448 } 449 } 450 451 xpt_register_async(0, ncr53c9x_async, sc->sc_sim, sc->sc_path); 452 xpt_free_path(sc->sc_path); 453 xpt_bus_deregister(cam_sim_path(sc->sc_sim)); |
454 cam_sim_free(sc->sc_sim, TRUE); |
|
452 453 NCR_UNLOCK(sc); 454 | 455 456 NCR_UNLOCK(sc); 457 |
455 cam_sim_free(sc->sc_sim, TRUE); | |
456 free(sc->ecb_array, M_DEVBUF); 457 free(sc->sc_tinfo, M_DEVBUF); 458 if (sc->sc_imess_self) 459 free(sc->sc_imess, M_DEVBUF); 460 if (sc->sc_omess_self) 461 free(sc->sc_omess, M_DEVBUF); 462 463 return (0); --- 35 unchanged lines hidden (view full) --- 499 case NCR_VARIANT_NCR53C94: 500 case NCR_VARIANT_NCR53C96: 501 case NCR_VARIANT_ESP200: 502 sc->sc_features |= NCR_F_HASCFG3; 503 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 504 /* FALLTHROUGH */ 505 case NCR_VARIANT_ESP100A: 506 sc->sc_features |= NCR_F_SELATN3; | 458 free(sc->ecb_array, M_DEVBUF); 459 free(sc->sc_tinfo, M_DEVBUF); 460 if (sc->sc_imess_self) 461 free(sc->sc_imess, M_DEVBUF); 462 if (sc->sc_omess_self) 463 free(sc->sc_omess, M_DEVBUF); 464 465 return (0); --- 35 unchanged lines hidden (view full) --- 501 case NCR_VARIANT_NCR53C94: 502 case NCR_VARIANT_NCR53C96: 503 case NCR_VARIANT_ESP200: 504 sc->sc_features |= NCR_F_HASCFG3; 505 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 506 /* FALLTHROUGH */ 507 case NCR_VARIANT_ESP100A: 508 sc->sc_features |= NCR_F_SELATN3; |
509 if ((sc->sc_cfg2 & NCRCFG2_FE) != 0) 510 sc->sc_features |= NCR_F_LARGEXFER; |
|
507 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 508 /* FALLTHROUGH */ 509 case NCR_VARIANT_ESP100: 510 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); 511 NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf); 512 NCR_WRITE_REG(sc, NCR_SYNCOFF, 0); 513 NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout); 514 break; 515 516 case NCR_VARIANT_FAS366: | 511 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 512 /* FALLTHROUGH */ 513 case NCR_VARIANT_ESP100: 514 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); 515 NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf); 516 NCR_WRITE_REG(sc, NCR_SYNCOFF, 0); 517 NCR_WRITE_REG(sc, NCR_TIMEOUT, sc->sc_timeout); 518 break; 519 520 case NCR_VARIANT_FAS366: |
517 sc->sc_features |= 518 NCR_F_HASCFG3 | NCR_F_FASTSCSI | NCR_F_SELATN3; | 521 sc->sc_features |= NCR_F_HASCFG3 | NCR_F_FASTSCSI | 522 NCR_F_SELATN3 | NCR_F_LARGEXFER; |
519 sc->sc_cfg3 = NCRFASCFG3_FASTCLK | NCRFASCFG3_OBAUTO; 520 if (sc->sc_id > 7) 521 sc->sc_cfg3 |= NCRFASCFG3_IDBIT3; 522 sc->sc_cfg3_fscsi = NCRFASCFG3_FASTSCSI; 523 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 524 sc->sc_cfg2 = NCRCFG2_HMEFE | NCRCFG2_HME32; 525 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 526 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); --- 179 unchanged lines hidden (view full) --- 706 /* Only the step bits are of interest. */ 707 sc->sc_espstep = NCR_READ_REG(sc, NCR_STEP) & NCRSTEP_MASK; 708 709 if (sc->sc_rev == NCR_VARIANT_FAS366) 710 sc->sc_espstat2 = NCR_READ_REG(sc, NCR_STAT2); 711 712 sc->sc_espintr = NCR_READ_REG(sc, NCR_INTR); 713 | 523 sc->sc_cfg3 = NCRFASCFG3_FASTCLK | NCRFASCFG3_OBAUTO; 524 if (sc->sc_id > 7) 525 sc->sc_cfg3 |= NCRFASCFG3_IDBIT3; 526 sc->sc_cfg3_fscsi = NCRFASCFG3_FASTSCSI; 527 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 528 sc->sc_cfg2 = NCRCFG2_HMEFE | NCRCFG2_HME32; 529 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 530 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); --- 179 unchanged lines hidden (view full) --- 710 /* Only the step bits are of interest. */ 711 sc->sc_espstep = NCR_READ_REG(sc, NCR_STEP) & NCRSTEP_MASK; 712 713 if (sc->sc_rev == NCR_VARIANT_FAS366) 714 sc->sc_espstat2 = NCR_READ_REG(sc, NCR_STAT2); 715 716 sc->sc_espintr = NCR_READ_REG(sc, NCR_INTR); 717 |
714 if (sc->sc_glue->gl_clear_latched_intr != NULL) 715 (*sc->sc_glue->gl_clear_latched_intr)(sc); 716 | |
717 /* 718 * Determine the SCSI bus phase, return either a real SCSI bus phase 719 * or some pseudo phase we use to detect certain exceptions. 720 */ 721 sc->sc_phase = (sc->sc_espintr & NCRINTR_DIS) ? 722 BUSFREE_PHASE : sc->sc_espstat & NCRSTAT_PHASE; 723 724 NCR_INTS(("regs[intr=%02x,stat=%02x,step=%02x,stat2=%02x] ", --- 76 unchanged lines hidden (view full) --- 801 * by DMA instead of programmed I/O soon. 802 */ 803static void 804ncr53c9x_select(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb) 805{ 806 struct ncr53c9x_tinfo *ti; 807 uint8_t *cmd; 808 size_t dmasize; | 718 /* 719 * Determine the SCSI bus phase, return either a real SCSI bus phase 720 * or some pseudo phase we use to detect certain exceptions. 721 */ 722 sc->sc_phase = (sc->sc_espintr & NCRINTR_DIS) ? 723 BUSFREE_PHASE : sc->sc_espstat & NCRSTAT_PHASE; 724 725 NCR_INTS(("regs[intr=%02x,stat=%02x,step=%02x,stat2=%02x] ", --- 76 unchanged lines hidden (view full) --- 802 * by DMA instead of programmed I/O soon. 803 */ 804static void 805ncr53c9x_select(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb) 806{ 807 struct ncr53c9x_tinfo *ti; 808 uint8_t *cmd; 809 size_t dmasize; |
809 int clen, selatn3, selatns; | 810 int clen, error, selatn3, selatns; |
810 int lun = ecb->ccb->ccb_h.target_lun; 811 int target = ecb->ccb->ccb_h.target_id; 812 813 NCR_LOCK_ASSERT(sc, MA_OWNED); 814 815 NCR_TRACE(("[%s(t%d,l%d,cmd:%x,tag:%x,%x)] ", __func__, target, lun, 816 ecb->cmd.cmd.opcode, ecb->tag[0], ecb->tag[1])); 817 --- 64 unchanged lines hidden (view full) --- 882 cmd[0] = MSG_IDENTIFY(lun, (ti->flags & T_RSELECTOFF) == 0); 883 } 884 885 if ((sc->sc_features & NCR_F_DMASELECT) && !selatns) { 886 /* Setup DMA transfer for command. */ 887 dmasize = clen; 888 sc->sc_cmdlen = clen; 889 sc->sc_cmdp = cmd; | 811 int lun = ecb->ccb->ccb_h.target_lun; 812 int target = ecb->ccb->ccb_h.target_id; 813 814 NCR_LOCK_ASSERT(sc, MA_OWNED); 815 816 NCR_TRACE(("[%s(t%d,l%d,cmd:%x,tag:%x,%x)] ", __func__, target, lun, 817 ecb->cmd.cmd.opcode, ecb->tag[0], ecb->tag[1])); 818 --- 64 unchanged lines hidden (view full) --- 883 cmd[0] = MSG_IDENTIFY(lun, (ti->flags & T_RSELECTOFF) == 0); 884 } 885 886 if ((sc->sc_features & NCR_F_DMASELECT) && !selatns) { 887 /* Setup DMA transfer for command. */ 888 dmasize = clen; 889 sc->sc_cmdlen = clen; 890 sc->sc_cmdp = cmd; |
890 NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize); | 891 error = NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, 892 &dmasize); 893 if (error != 0) { 894 sc->sc_cmdlen = 0; 895 sc->sc_cmdp = NULL; 896 goto cmd; 897 } 898 |
891 /* Program the SCSI counter. */ 892 NCR_SET_COUNT(sc, dmasize); 893 894 /* Load the count in. */ | 899 /* Program the SCSI counter. */ 900 NCR_SET_COUNT(sc, dmasize); 901 902 /* Load the count in. */ |
895 /* if (sc->sc_rev != NCR_VARIANT_FAS366) */ 896 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); | 903 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); |
897 898 /* And get the target's attention. */ 899 if (selatn3) { 900 sc->sc_msgout = SEND_TAG; 901 sc->sc_flags |= NCR_ATN; 902 NCRCMD(sc, NCRCMD_SELATN3 | NCRCMD_DMA); 903 } else 904 NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA); 905 NCRDMA_GO(sc); 906 return; 907 } 908 | 904 905 /* And get the target's attention. */ 906 if (selatn3) { 907 sc->sc_msgout = SEND_TAG; 908 sc->sc_flags |= NCR_ATN; 909 NCRCMD(sc, NCRCMD_SELATN3 | NCRCMD_DMA); 910 } else 911 NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA); 912 NCRDMA_GO(sc); 913 return; 914 } 915 |
916cmd: |
|
909 /* 910 * Who am I? This is where we tell the target that we are 911 * happy for it to disconnect etc. 912 */ 913 914 /* Now get the command into the FIFO. */ 915 ncr53c9x_wrfifo(sc, cmd, clen); 916 --- 67 unchanged lines hidden (view full) --- 984 NCR_LOCK_ASSERT(sc, MA_OWNED); 985 986 NCR_TRACE(("[%s %d]", __func__, ccb->ccb_h.func_code)); 987 988 switch (ccb->ccb_h.func_code) { 989 case XPT_RESET_BUS: 990 ncr53c9x_init(sc, 1); 991 ccb->ccb_h.status = CAM_REQ_CMP; | 917 /* 918 * Who am I? This is where we tell the target that we are 919 * happy for it to disconnect etc. 920 */ 921 922 /* Now get the command into the FIFO. */ 923 ncr53c9x_wrfifo(sc, cmd, clen); 924 --- 67 unchanged lines hidden (view full) --- 992 NCR_LOCK_ASSERT(sc, MA_OWNED); 993 994 NCR_TRACE(("[%s %d]", __func__, ccb->ccb_h.func_code)); 995 996 switch (ccb->ccb_h.func_code) { 997 case XPT_RESET_BUS: 998 ncr53c9x_init(sc, 1); 999 ccb->ccb_h.status = CAM_REQ_CMP; |
992 xpt_done(ccb); 993 return; | 1000 break; |
994 995 case XPT_CALC_GEOMETRY: 996 cam_calc_geometry(&ccb->ccg, sc->sc_extended_geom); | 1001 1002 case XPT_CALC_GEOMETRY: 1003 cam_calc_geometry(&ccb->ccg, sc->sc_extended_geom); |
997 xpt_done(ccb); 998 return; | 1004 break; |
999 1000 case XPT_PATH_INQ: 1001 cpi = &ccb->cpi; 1002 cpi->version_num = 1; 1003 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 1004 cpi->hba_inquiry |= 1005 (sc->sc_rev == NCR_VARIANT_FAS366) ? PI_WIDE_16 : 0; 1006 cpi->target_sprt = 0; 1007 cpi->hba_misc = 0; 1008 cpi->hba_eng_cnt = 0; 1009 cpi->max_target = sc->sc_ntarg - 1; 1010 cpi->max_lun = 7; 1011 cpi->initiator_id = sc->sc_id; | 1005 1006 case XPT_PATH_INQ: 1007 cpi = &ccb->cpi; 1008 cpi->version_num = 1; 1009 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 1010 cpi->hba_inquiry |= 1011 (sc->sc_rev == NCR_VARIANT_FAS366) ? PI_WIDE_16 : 0; 1012 cpi->target_sprt = 0; 1013 cpi->hba_misc = 0; 1014 cpi->hba_eng_cnt = 0; 1015 cpi->max_target = sc->sc_ntarg - 1; 1016 cpi->max_lun = 7; 1017 cpi->initiator_id = sc->sc_id; |
1012 cpi->bus_id = 0; 1013 cpi->base_transfer_speed = 3300; | |
1014 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); | 1018 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); |
1015 strncpy(cpi->hba_vid, "Sun", HBA_IDLEN); | 1019 strncpy(cpi->hba_vid, "NCR", HBA_IDLEN); |
1016 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1017 cpi->unit_number = cam_sim_unit(sim); | 1020 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1021 cpi->unit_number = cam_sim_unit(sim); |
1018 cpi->transport = XPORT_SPI; 1019 cpi->transport_version = 2; | 1022 cpi->bus_id = 0; 1023 cpi->base_transfer_speed = 3300; |
1020 cpi->protocol = PROTO_SCSI; 1021 cpi->protocol_version = SCSI_REV_2; | 1024 cpi->protocol = PROTO_SCSI; 1025 cpi->protocol_version = SCSI_REV_2; |
1026 cpi->transport = XPORT_SPI; 1027 cpi->transport_version = 2; 1028 cpi->maxio = sc->sc_maxxfer; |
|
1022 ccb->ccb_h.status = CAM_REQ_CMP; | 1029 ccb->ccb_h.status = CAM_REQ_CMP; |
1023 xpt_done(ccb); 1024 return; | 1030 break; |
1025 1026 case XPT_GET_TRAN_SETTINGS: 1027 cts = &ccb->cts; 1028 ti = &sc->sc_tinfo[ccb->ccb_h.target_id]; 1029 scsi = &cts->proto_specific.scsi; 1030 spi = &cts->xport_specific.spi; 1031 1032 cts->protocol = PROTO_SCSI; --- 26 unchanged lines hidden (view full) --- 1059 } 1060 spi->valid = 1061 CTS_SPI_VALID_BUS_WIDTH | 1062 CTS_SPI_VALID_SYNC_RATE | 1063 CTS_SPI_VALID_SYNC_OFFSET | 1064 CTS_SPI_VALID_DISC; 1065 scsi->valid = CTS_SCSI_VALID_TQ; 1066 ccb->ccb_h.status = CAM_REQ_CMP; | 1031 1032 case XPT_GET_TRAN_SETTINGS: 1033 cts = &ccb->cts; 1034 ti = &sc->sc_tinfo[ccb->ccb_h.target_id]; 1035 scsi = &cts->proto_specific.scsi; 1036 spi = &cts->xport_specific.spi; 1037 1038 cts->protocol = PROTO_SCSI; --- 26 unchanged lines hidden (view full) --- 1065 } 1066 spi->valid = 1067 CTS_SPI_VALID_BUS_WIDTH | 1068 CTS_SPI_VALID_SYNC_RATE | 1069 CTS_SPI_VALID_SYNC_OFFSET | 1070 CTS_SPI_VALID_DISC; 1071 scsi->valid = CTS_SCSI_VALID_TQ; 1072 ccb->ccb_h.status = CAM_REQ_CMP; |
1067 xpt_done(ccb); 1068 return; | 1073 break; |
1069 1070 case XPT_ABORT: 1071 device_printf(sc->sc_dev, "XPT_ABORT called\n"); 1072 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; | 1074 1075 case XPT_ABORT: 1076 device_printf(sc->sc_dev, "XPT_ABORT called\n"); 1077 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; |
1073 xpt_done(ccb); 1074 return; | 1078 break; |
1075 1076 case XPT_TERM_IO: 1077 device_printf(sc->sc_dev, "XPT_TERM_IO called\n"); 1078 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; | 1079 1080 case XPT_TERM_IO: 1081 device_printf(sc->sc_dev, "XPT_TERM_IO called\n"); 1082 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; |
1079 xpt_done(ccb); 1080 return; | 1083 break; |
1081 1082 case XPT_RESET_DEV: 1083 case XPT_SCSI_IO: 1084 if (ccb->ccb_h.target_id < 0 || 1085 ccb->ccb_h.target_id >= sc->sc_ntarg) { 1086 ccb->ccb_h.status = CAM_PATH_INVALID; | 1084 1085 case XPT_RESET_DEV: 1086 case XPT_SCSI_IO: 1087 if (ccb->ccb_h.target_id < 0 || 1088 ccb->ccb_h.target_id >= sc->sc_ntarg) { 1089 ccb->ccb_h.status = CAM_PATH_INVALID; |
1087 xpt_done(ccb); 1088 return; | 1090 goto done; |
1089 } 1090 /* Get an ECB to use. */ 1091 ecb = ncr53c9x_get_ecb(sc); 1092 /* 1093 * This should never happen as we track resources 1094 * in the mid-layer. 1095 */ 1096 if (ecb == NULL) { 1097 xpt_freeze_simq(sim, 1); 1098 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1099 device_printf(sc->sc_dev, "unable to allocate ecb\n"); | 1091 } 1092 /* Get an ECB to use. */ 1093 ecb = ncr53c9x_get_ecb(sc); 1094 /* 1095 * This should never happen as we track resources 1096 * in the mid-layer. 1097 */ 1098 if (ecb == NULL) { 1099 xpt_freeze_simq(sim, 1); 1100 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1101 device_printf(sc->sc_dev, "unable to allocate ecb\n"); |
1100 xpt_done(ccb); 1101 return; | 1102 goto done; |
1102 } 1103 1104 /* Initialize ecb. */ 1105 ecb->ccb = ccb; 1106 ecb->timeout = ccb->ccb_h.timeout; 1107 1108 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 1109 ecb->flags |= ECB_RESET; --- 12 unchanged lines hidden (view full) --- 1122 ecb->dleft = csio->dxfer_len; 1123 } 1124 ecb->stat = 0; 1125 1126 TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain); 1127 ecb->flags |= ECB_READY; 1128 if (sc->sc_state == NCR_IDLE) 1129 ncr53c9x_sched(sc); | 1103 } 1104 1105 /* Initialize ecb. */ 1106 ecb->ccb = ccb; 1107 ecb->timeout = ccb->ccb_h.timeout; 1108 1109 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 1110 ecb->flags |= ECB_RESET; --- 12 unchanged lines hidden (view full) --- 1123 ecb->dleft = csio->dxfer_len; 1124 } 1125 ecb->stat = 0; 1126 1127 TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain); 1128 ecb->flags |= ECB_READY; 1129 if (sc->sc_state == NCR_IDLE) 1130 ncr53c9x_sched(sc); |
1130 break; | 1131 return; |
1131 1132 case XPT_SET_TRAN_SETTINGS: 1133 cts = &ccb->cts; 1134 target = ccb->ccb_h.target_id; 1135 ti = &sc->sc_tinfo[target]; 1136 scsi = &cts->proto_specific.scsi; 1137 spi = &cts->xport_specific.spi; 1138 --- 21 unchanged lines hidden (view full) --- 1160 1161 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { 1162 NCR_MISC(("%s: target %d: sync offset negotiation\n", 1163 device_get_nameunit(sc->sc_dev), target)); 1164 ti->goal.offset = spi->sync_offset; 1165 } 1166 1167 ccb->ccb_h.status = CAM_REQ_CMP; | 1132 1133 case XPT_SET_TRAN_SETTINGS: 1134 cts = &ccb->cts; 1135 target = ccb->ccb_h.target_id; 1136 ti = &sc->sc_tinfo[target]; 1137 scsi = &cts->proto_specific.scsi; 1138 spi = &cts->xport_specific.spi; 1139 --- 21 unchanged lines hidden (view full) --- 1161 1162 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { 1163 NCR_MISC(("%s: target %d: sync offset negotiation\n", 1164 device_get_nameunit(sc->sc_dev), target)); 1165 ti->goal.offset = spi->sync_offset; 1166 } 1167 1168 ccb->ccb_h.status = CAM_REQ_CMP; |
1168 xpt_done(ccb); 1169 return; | 1169 break; |
1170 1171 default: 1172 device_printf(sc->sc_dev, "Unhandled function code %d\n", 1173 ccb->ccb_h.func_code); 1174 ccb->ccb_h.status = CAM_PROVIDE_FAIL; | 1170 1171 default: 1172 device_printf(sc->sc_dev, "Unhandled function code %d\n", 1173 ccb->ccb_h.func_code); 1174 ccb->ccb_h.status = CAM_PROVIDE_FAIL; |
1175 xpt_done(ccb); 1176 return; | |
1177 } | 1175 } |
1176 1177done: 1178 xpt_done(ccb); |
|
1178} 1179 1180/* 1181 * Used when interrupt driven I/O is not allowed, e.g. during boot. 1182 */ 1183static void 1184ncr53c9x_poll(struct cam_sim *sim) 1185{ --- 839 unchanged lines hidden (view full) --- 2025 ncr53c9x_sched_msgout(SEND_WDTR); 2026 ti->flags &= ~T_WDTRSENT; 2027 ti->goal.width = ti->curr.width; 2028 ncr53c9x_setsync(sc, ti); 2029 break; 2030 2031 default: 2032 xpt_print_path(ecb->ccb->ccb_h.path); | 1179} 1180 1181/* 1182 * Used when interrupt driven I/O is not allowed, e.g. during boot. 1183 */ 1184static void 1185ncr53c9x_poll(struct cam_sim *sim) 1186{ --- 839 unchanged lines hidden (view full) --- 2026 ncr53c9x_sched_msgout(SEND_WDTR); 2027 ti->flags &= ~T_WDTRSENT; 2028 ti->goal.width = ti->curr.width; 2029 ncr53c9x_setsync(sc, ti); 2030 break; 2031 2032 default: 2033 xpt_print_path(ecb->ccb->ccb_h.path); |
2033 printf("unrecognized MESSAGE EXTENDED;" 2034 " sending REJECT\n"); | 2034 printf("unrecognized MESSAGE EXTENDED 0x%x;" 2035 " sending REJECT\n", sc->sc_imess[2]); |
2035 goto reject; 2036 } 2037 break; 2038 2039 default: 2040 NCR_MSGS(("ident ")); 2041 xpt_print_path(ecb->ccb->ccb_h.path); | 2036 goto reject; 2037 } 2038 break; 2039 2040 default: 2041 NCR_MSGS(("ident ")); 2042 xpt_print_path(ecb->ccb->ccb_h.path); |
2042 printf("unrecognized MESSAGE; sending REJECT\n"); | 2043 printf("unrecognized MESSAGE 0x%x; sending REJECT\n", 2044 sc->sc_imess[0]); |
2043 /* FALLTHROUGH */ 2044 reject: 2045 ncr53c9x_sched_msgout(SEND_REJECT); 2046 break; 2047 } 2048 break; 2049 2050 case NCR_IDENTIFIED: --- 53 unchanged lines hidden (view full) --- 2104 * Send the highest priority, scheduled message. 2105 */ 2106static void 2107ncr53c9x_msgout(struct ncr53c9x_softc *sc) 2108{ 2109 struct ncr53c9x_tinfo *ti; 2110 struct ncr53c9x_ecb *ecb; 2111 size_t size; | 2045 /* FALLTHROUGH */ 2046 reject: 2047 ncr53c9x_sched_msgout(SEND_REJECT); 2048 break; 2049 } 2050 break; 2051 2052 case NCR_IDENTIFIED: --- 53 unchanged lines hidden (view full) --- 2106 * Send the highest priority, scheduled message. 2107 */ 2108static void 2109ncr53c9x_msgout(struct ncr53c9x_softc *sc) 2110{ 2111 struct ncr53c9x_tinfo *ti; 2112 struct ncr53c9x_ecb *ecb; 2113 size_t size; |
2114 int error; |
|
2112#ifdef NCR53C9X_DEBUG 2113 int i; 2114#endif 2115 2116 NCR_LOCK_ASSERT(sc, MA_OWNED); 2117 2118 NCR_TRACE(("[%s(priq:%x, prevphase:%x)]", __func__, sc->sc_msgpriq, 2119 sc->sc_prevphase)); --- 121 unchanged lines hidden (view full) --- 2241#ifdef NCR53C9X_DEBUG 2242 if ((ncr53c9x_debug & NCR_SHOWMSGS) != 0) { 2243 NCR_MSGS(("<msgout:")); 2244 for (i = 0; i < sc->sc_omlen; i++) 2245 NCR_MSGS((" %02x", sc->sc_omess[i])); 2246 NCR_MSGS(("> ")); 2247 } 2248#endif | 2115#ifdef NCR53C9X_DEBUG 2116 int i; 2117#endif 2118 2119 NCR_LOCK_ASSERT(sc, MA_OWNED); 2120 2121 NCR_TRACE(("[%s(priq:%x, prevphase:%x)]", __func__, sc->sc_msgpriq, 2122 sc->sc_prevphase)); --- 121 unchanged lines hidden (view full) --- 2244#ifdef NCR53C9X_DEBUG 2245 if ((ncr53c9x_debug & NCR_SHOWMSGS) != 0) { 2246 NCR_MSGS(("<msgout:")); 2247 for (i = 0; i < sc->sc_omlen; i++) 2248 NCR_MSGS((" %02x", sc->sc_omess[i])); 2249 NCR_MSGS(("> ")); 2250 } 2251#endif |
2249 if (sc->sc_rev == NCR_VARIANT_FAS366) { 2250 /* 2251 * XXX FIFO size 2252 */ 2253 ncr53c9x_flushfifo(sc); 2254 ncr53c9x_wrfifo(sc, sc->sc_omp, sc->sc_omlen); 2255 NCRCMD(sc, NCRCMD_TRANS); 2256 } else { | 2252 2253 if (sc->sc_rev != NCR_VARIANT_FAS366) { |
2257 /* (Re)send the message. */ 2258 size = ulmin(sc->sc_omlen, sc->sc_maxxfer); | 2254 /* (Re)send the message. */ 2255 size = ulmin(sc->sc_omlen, sc->sc_maxxfer); |
2259 NCRDMA_SETUP(sc, &sc->sc_omp, &sc->sc_omlen, 0, &size); | 2256 error = NCRDMA_SETUP(sc, &sc->sc_omp, &sc->sc_omlen, 0, &size); 2257 if (error != 0) 2258 goto cmd; 2259 |
2260 /* Program the SCSI counter. */ 2261 NCR_SET_COUNT(sc, size); 2262 2263 /* Load the count in and start the message-out transfer. */ 2264 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 2265 NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA); 2266 NCRDMA_GO(sc); | 2260 /* Program the SCSI counter. */ 2261 NCR_SET_COUNT(sc, size); 2262 2263 /* Load the count in and start the message-out transfer. */ 2264 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 2265 NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA); 2266 NCRDMA_GO(sc); |
2267 return; |
|
2267 } | 2268 } |
2269 2270cmd: 2271 /* 2272 * XXX FIFO size 2273 */ 2274 ncr53c9x_flushfifo(sc); 2275 ncr53c9x_wrfifo(sc, sc->sc_omp, sc->sc_omlen); 2276 NCRCMD(sc, NCRCMD_TRANS); |
|
2268} 2269 2270void 2271ncr53c9x_intr(void *arg) 2272{ 2273 struct ncr53c9x_softc *sc = arg; 2274 2275 if (!NCRDMA_ISINTR(sc)) --- 18 unchanged lines hidden (view full) --- 2294static void 2295ncr53c9x_intr1(struct ncr53c9x_softc *sc) 2296{ 2297 struct ncr53c9x_ecb *ecb; 2298 struct ncr53c9x_linfo *li; 2299 struct ncr53c9x_tinfo *ti; 2300 struct timeval cur, wait; 2301 size_t size; | 2277} 2278 2279void 2280ncr53c9x_intr(void *arg) 2281{ 2282 struct ncr53c9x_softc *sc = arg; 2283 2284 if (!NCRDMA_ISINTR(sc)) --- 18 unchanged lines hidden (view full) --- 2303static void 2304ncr53c9x_intr1(struct ncr53c9x_softc *sc) 2305{ 2306 struct ncr53c9x_ecb *ecb; 2307 struct ncr53c9x_linfo *li; 2308 struct ncr53c9x_tinfo *ti; 2309 struct timeval cur, wait; 2310 size_t size; |
2302 int i, nfifo; | 2311 int error, i, nfifo; |
2303 uint8_t msg; 2304 2305 NCR_LOCK_ASSERT(sc, MA_OWNED); 2306 2307 NCR_INTS(("[ncr53c9x_intr: state %d]", sc->sc_state)); 2308 2309again: 2310 /* and what do the registers say... */ --- 658 unchanged lines hidden (view full) --- 2969 NCRCMD(sc, NCRCMD_SETATN); 2970 sc->sc_flags |= NCR_ATN; 2971 } 2972 if (sc->sc_features & NCR_F_DMASELECT) { 2973 /* Setup DMA transfer for command. */ 2974 size = ecb->clen; 2975 sc->sc_cmdlen = size; 2976 sc->sc_cmdp = (void *)&ecb->cmd.cmd; | 2312 uint8_t msg; 2313 2314 NCR_LOCK_ASSERT(sc, MA_OWNED); 2315 2316 NCR_INTS(("[ncr53c9x_intr: state %d]", sc->sc_state)); 2317 2318again: 2319 /* and what do the registers say... */ --- 658 unchanged lines hidden (view full) --- 2978 NCRCMD(sc, NCRCMD_SETATN); 2979 sc->sc_flags |= NCR_ATN; 2980 } 2981 if (sc->sc_features & NCR_F_DMASELECT) { 2982 /* Setup DMA transfer for command. */ 2983 size = ecb->clen; 2984 sc->sc_cmdlen = size; 2985 sc->sc_cmdp = (void *)&ecb->cmd.cmd; |
2977 NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, | 2986 error = NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, |
2978 0, &size); | 2987 0, &size); |
2988 if (error != 0) { 2989 sc->sc_cmdlen = 0; 2990 sc->sc_cmdp = NULL; 2991 goto cmd; 2992 } 2993 |
|
2979 /* Program the SCSI counter. */ 2980 NCR_SET_COUNT(sc, size); 2981 2982 /* Load the count in. */ 2983 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 2984 2985 /* Start the command transfer. */ 2986 NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA); 2987 NCRDMA_GO(sc); | 2994 /* Program the SCSI counter. */ 2995 NCR_SET_COUNT(sc, size); 2996 2997 /* Load the count in. */ 2998 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 2999 3000 /* Start the command transfer. */ 3001 NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA); 3002 NCRDMA_GO(sc); |
2988 } else { 2989 ncr53c9x_wrfifo(sc, (uint8_t *)&ecb->cmd.cmd, 2990 ecb->clen); 2991 NCRCMD(sc, NCRCMD_TRANS); | 3003 sc->sc_prevphase = COMMAND_PHASE; 3004 break; |
2992 } | 3005 } |
3006cmd: 3007 ncr53c9x_wrfifo(sc, (uint8_t *)&ecb->cmd.cmd, ecb->clen); 3008 NCRCMD(sc, NCRCMD_TRANS); |
|
2993 sc->sc_prevphase = COMMAND_PHASE; 2994 break; 2995 2996 case DATA_OUT_PHASE: 2997 NCR_PHASE(("DATA_OUT_PHASE [%ld] ", (long)sc->sc_dleft)); | 3009 sc->sc_prevphase = COMMAND_PHASE; 3010 break; 3011 3012 case DATA_OUT_PHASE: 3013 NCR_PHASE(("DATA_OUT_PHASE [%ld] ", (long)sc->sc_dleft)); |
3014 sc->sc_prevphase = DATA_OUT_PHASE; |
|
2998 NCRCMD(sc, NCRCMD_FLUSH); 2999 size = ulmin(sc->sc_dleft, sc->sc_maxxfer); | 3015 NCRCMD(sc, NCRCMD_FLUSH); 3016 size = ulmin(sc->sc_dleft, sc->sc_maxxfer); |
3000 NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft, 0, &size); 3001 sc->sc_prevphase = DATA_OUT_PHASE; | 3017 error = NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft, 0, &size); |
3002 goto setup_xfer; 3003 3004 case DATA_IN_PHASE: 3005 NCR_PHASE(("DATA_IN_PHASE ")); | 3018 goto setup_xfer; 3019 3020 case DATA_IN_PHASE: 3021 NCR_PHASE(("DATA_IN_PHASE ")); |
3022 sc->sc_prevphase = DATA_IN_PHASE; |
|
3006 if (sc->sc_rev == NCR_VARIANT_ESP100) 3007 NCRCMD(sc, NCRCMD_FLUSH); 3008 size = ulmin(sc->sc_dleft, sc->sc_maxxfer); | 3023 if (sc->sc_rev == NCR_VARIANT_ESP100) 3024 NCRCMD(sc, NCRCMD_FLUSH); 3025 size = ulmin(sc->sc_dleft, sc->sc_maxxfer); |
3009 NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft, 1, &size); 3010 sc->sc_prevphase = DATA_IN_PHASE; 3011 setup_xfer: | 3026 error = NCRDMA_SETUP(sc, &sc->sc_dp, &sc->sc_dleft, 1, &size); 3027setup_xfer: 3028 if (error != 0) { 3029 switch (error) { 3030 case EFBIG: 3031 ecb->ccb->ccb_h.status |= CAM_REQ_TOO_BIG; 3032 break; 3033 case EINPROGRESS: 3034 panic("%s: cannot deal with deferred DMA", 3035 __func__); 3036 case EINVAL: 3037 ecb->ccb->ccb_h.status |= CAM_REQ_INVALID; 3038 break; 3039 case ENOMEM: 3040 ecb->ccb->ccb_h.status |= CAM_REQUEUE_REQ; 3041 break; 3042 default: 3043 ecb->ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 3044 } 3045 goto finish; 3046 } 3047 |
3012 /* Target returned to data phase: wipe "done" memory */ 3013 ecb->flags &= ~ECB_TENTATIVE_DONE; 3014 3015 /* Program the SCSI counter. */ 3016 NCR_SET_COUNT(sc, size); 3017 3018 /* Load the count in. */ 3019 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); --- 182 unchanged lines hidden --- | 3048 /* Target returned to data phase: wipe "done" memory */ 3049 ecb->flags &= ~ECB_TENTATIVE_DONE; 3050 3051 /* Program the SCSI counter. */ 3052 NCR_SET_COUNT(sc, size); 3053 3054 /* Load the count in. */ 3055 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); --- 182 unchanged lines hidden --- |