Sun Jul 31 18:39:00 2011 UTC ()
simple_lock to mutex conversion.


(jakllsch)
diff -r1.142 -r1.143 src/sys/dev/ic/ncr53c9x.c
diff -r1.54 -r1.55 src/sys/dev/ic/ncr53c9xvar.h

cvs diff -r1.142 -r1.143 src/sys/dev/ic/ncr53c9x.c (expand / switch to unified diff)

--- src/sys/dev/ic/ncr53c9x.c 2011/07/04 16:06:17 1.142
+++ src/sys/dev/ic/ncr53c9x.c 2011/07/31 18:39:00 1.143
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ncr53c9x.c,v 1.142 2011/07/04 16:06:17 joerg Exp $ */ 1/* $NetBSD: ncr53c9x.c,v 1.143 2011/07/31 18:39:00 jakllsch Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum. 8 * by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -60,27 +60,27 @@ @@ -60,27 +60,27 @@
60 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 60 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE. 61 * POSSIBILITY OF SUCH DAMAGE.
62 */ 62 */
63 63
64/* 64/*
65 * Based on aic6360 by Jarle Greipsland 65 * Based on aic6360 by Jarle Greipsland
66 * 66 *
67 * Acknowledgements: Many of the algorithms used in this driver are 67 * Acknowledgements: Many of the algorithms used in this driver are
68 * inspired by the work of Julian Elischer (julian@tfs.com) and 68 * inspired by the work of Julian Elischer (julian@tfs.com) and
69 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million! 69 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
70 */ 70 */
71 71
72#include <sys/cdefs.h> 72#include <sys/cdefs.h>
73__KERNEL_RCSID(0, "$NetBSD: ncr53c9x.c,v 1.142 2011/07/04 16:06:17 joerg Exp $"); 73__KERNEL_RCSID(0, "$NetBSD: ncr53c9x.c,v 1.143 2011/07/31 18:39:00 jakllsch Exp $");
74 74
75#include <sys/param.h> 75#include <sys/param.h>
76#include <sys/systm.h> 76#include <sys/systm.h>
77#include <sys/callout.h> 77#include <sys/callout.h>
78#include <sys/kernel.h> 78#include <sys/kernel.h>
79#include <sys/errno.h> 79#include <sys/errno.h>
80#include <sys/ioctl.h> 80#include <sys/ioctl.h>
81#include <sys/device.h> 81#include <sys/device.h>
82#include <sys/buf.h> 82#include <sys/buf.h>
83#include <sys/malloc.h> 83#include <sys/malloc.h>
84#include <sys/proc.h> 84#include <sys/proc.h>
85#include <sys/queue.h> 85#include <sys/queue.h>
86#include <sys/pool.h> 86#include <sys/pool.h>
@@ -184,27 +184,27 @@ ncr53c9x_lunsearch(struct ncr53c9x_tinfo @@ -184,27 +184,27 @@ ncr53c9x_lunsearch(struct ncr53c9x_tinfo
184 return li; 184 return li;
185 return NULL; 185 return NULL;
186} 186}
187 187
188/* 188/*
189 * Attach this instance, and then all the sub-devices 189 * Attach this instance, and then all the sub-devices
190 */ 190 */
191void 191void
192ncr53c9x_attach(struct ncr53c9x_softc *sc) 192ncr53c9x_attach(struct ncr53c9x_softc *sc)
193{ 193{
194 struct scsipi_adapter *adapt = &sc->sc_adapter; 194 struct scsipi_adapter *adapt = &sc->sc_adapter;
195 struct scsipi_channel *chan = &sc->sc_channel; 195 struct scsipi_channel *chan = &sc->sc_channel;
196 196
197 simple_lock_init(&sc->sc_lock); 197 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
198 198
199 callout_init(&sc->sc_watchdog, 0); 199 callout_init(&sc->sc_watchdog, 0);
200 200
201 /* 201 /*
202 * Note, the front-end has set us up to print the chip variation. 202 * Note, the front-end has set us up to print the chip variation.
203 */ 203 */
204 if (sc->sc_rev >= NCR_VARIANT_MAX) { 204 if (sc->sc_rev >= NCR_VARIANT_MAX) {
205 aprint_error(": unknown variant %d, devices not attached\n", 205 aprint_error(": unknown variant %d, devices not attached\n",
206 sc->sc_rev); 206 sc->sc_rev);
207 return; 207 return;
208 } 208 }
209 209
210 aprint_normal(": %s, %dMHz, SCSI ID %d\n", 210 aprint_normal(": %s, %dMHz, SCSI ID %d\n",
@@ -331,26 +331,28 @@ ncr53c9x_detach(struct ncr53c9x_softc *s @@ -331,26 +331,28 @@ ncr53c9x_detach(struct ncr53c9x_softc *s
331 } 331 }
332 332
333 if (sc->sc_child) { 333 if (sc->sc_child) {
334 error = config_detach(sc->sc_child, flags); 334 error = config_detach(sc->sc_child, flags);
335 if (error) 335 if (error)
336 return error; 336 return error;
337 } 337 }
338 338
339 if (sc->sc_imess) 339 if (sc->sc_imess)
340 free(sc->sc_imess, M_DEVBUF); 340 free(sc->sc_imess, M_DEVBUF);
341 if (sc->sc_omess) 341 if (sc->sc_omess)
342 free(sc->sc_omess, M_DEVBUF); 342 free(sc->sc_omess, M_DEVBUF);
343 343
 344 mutex_destroy(&sc->sc_lock);
 345
344 return 0; 346 return 0;
345} 347}
346 348
347/* 349/*
348 * This is the generic ncr53c9x reset function. It does not reset the SCSI bus, 350 * This is the generic ncr53c9x reset function. It does not reset the SCSI bus,
349 * only this controller, but kills any on-going commands, and also stops 351 * only this controller, but kills any on-going commands, and also stops
350 * and resets the DMA. 352 * and resets the DMA.
351 * 353 *
352 * After reset, registers are loaded with the defaults from the attach 354 * After reset, registers are loaded with the defaults from the attach
353 * routine above. 355 * routine above.
354 */ 356 */
355void 357void
356ncr53c9x_reset(struct ncr53c9x_softc *sc) 358ncr53c9x_reset(struct ncr53c9x_softc *sc)
@@ -847,57 +849,55 @@ ncr53c9x_get_ecb(struct ncr53c9x_softc * @@ -847,57 +849,55 @@ ncr53c9x_get_ecb(struct ncr53c9x_softc *
847 * Start a SCSI-command 849 * Start a SCSI-command
848 * This function is called by the higher level SCSI-driver to queue/run 850 * This function is called by the higher level SCSI-driver to queue/run
849 * SCSI-commands. 851 * SCSI-commands.
850 */ 852 */
851 853
852void 854void
853ncr53c9x_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 855ncr53c9x_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
854 void *arg) 856 void *arg)
855{ 857{
856 struct scsipi_xfer *xs; 858 struct scsipi_xfer *xs;
857 struct scsipi_periph *periph; 859 struct scsipi_periph *periph;
858 struct ncr53c9x_softc *sc; 860 struct ncr53c9x_softc *sc;
859 struct ncr53c9x_ecb *ecb; 861 struct ncr53c9x_ecb *ecb;
860 int s, flags; 862 int flags;
861 863
862 NCR_TRACE(("[ncr53c9x_scsipi_request] ")); 864 NCR_TRACE(("[ncr53c9x_scsipi_request] "));
863 865
864 sc = device_private(chan->chan_adapter->adapt_dev); 866 sc = device_private(chan->chan_adapter->adapt_dev);
865 s = splbio(); 867 mutex_enter(&sc->sc_lock);
866 simple_lock(&sc->sc_lock); 
867 868
868 switch (req) { 869 switch (req) {
869 case ADAPTER_REQ_RUN_XFER: 870 case ADAPTER_REQ_RUN_XFER:
870 xs = arg; 871 xs = arg;
871 periph = xs->xs_periph; 872 periph = xs->xs_periph;
872 flags = xs->xs_control; 873 flags = xs->xs_control;
873 874
874 NCR_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen, 875 NCR_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
875 periph->periph_target)); 876 periph->periph_target));
876 877
877 /* Get an ECB to use. */ 878 /* Get an ECB to use. */
878 ecb = ncr53c9x_get_ecb(sc, xs->xs_control); 879 ecb = ncr53c9x_get_ecb(sc, xs->xs_control);
879 /* 880 /*
880 * This should never happen as we track resources 881 * This should never happen as we track resources
881 * in the mid-layer, but for now it can as pool_get() 882 * in the mid-layer, but for now it can as pool_get()
882 * can fail. 883 * can fail.
883 */ 884 */
884 if (ecb == NULL) { 885 if (ecb == NULL) {
885 scsipi_printaddr(periph); 886 scsipi_printaddr(periph);
886 printf("%s: unable to allocate ecb\n", 887 printf("%s: unable to allocate ecb\n",
887 device_xname(sc->sc_dev)); 888 device_xname(sc->sc_dev));
888 xs->error = XS_RESOURCE_SHORTAGE; 889 xs->error = XS_RESOURCE_SHORTAGE;
889 simple_unlock(&sc->sc_lock); 890 mutex_exit(&sc->sc_lock);
890 splx(s); 
891 scsipi_done(xs); 891 scsipi_done(xs);
892 return; 892 return;
893 } 893 }
894 894
895 /* Initialize ecb */ 895 /* Initialize ecb */
896 ecb->xs = xs; 896 ecb->xs = xs;
897 ecb->timeout = xs->timeout; 897 ecb->timeout = xs->timeout;
898 898
899 if (flags & XS_CTL_RESET) { 899 if (flags & XS_CTL_RESET) {
900 ecb->flags |= ECB_RESET; 900 ecb->flags |= ECB_RESET;
901 ecb->clen = 0; 901 ecb->clen = 0;
902 ecb->dleft = 0; 902 ecb->dleft = 0;
903 } else { 903 } else {
@@ -962,28 +962,27 @@ ncr53c9x_scsipi_request(struct scsipi_ch @@ -962,28 +962,27 @@ ncr53c9x_scsipi_request(struct scsipi_ch
962 ti->flags |= T_NEGOTIATE; 962 ti->flags |= T_NEGOTIATE;
963 ti->period = sc->sc_minsync; 963 ti->period = sc->sc_minsync;
964 } 964 }
965 /* 965 /*
966 * If we're not going to negotiate, send the notification 966 * If we're not going to negotiate, send the notification
967 * now, since it won't happen later. 967 * now, since it won't happen later.
968 */ 968 */
969 if ((ti->flags & T_NEGOTIATE) == 0) 969 if ((ti->flags & T_NEGOTIATE) == 0)
970 ncr53c9x_update_xfer_mode(sc, xm->xm_target); 970 ncr53c9x_update_xfer_mode(sc, xm->xm_target);
971 } 971 }
972 break; 972 break;
973 } 973 }
974 974
975 simple_unlock(&sc->sc_lock); 975 mutex_exit(&sc->sc_lock);
976 splx(s); 
977} 976}
978 977
979void 978void
980ncr53c9x_update_xfer_mode(struct ncr53c9x_softc *sc, int target) 979ncr53c9x_update_xfer_mode(struct ncr53c9x_softc *sc, int target)
981{ 980{
982 struct scsipi_xfer_mode xm; 981 struct scsipi_xfer_mode xm;
983 struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target]; 982 struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target];
984 983
985 xm.xm_target = target; 984 xm.xm_target = target;
986 xm.xm_mode = 0; 985 xm.xm_mode = 0;
987 xm.xm_period = 0; 986 xm.xm_period = 0;
988 xm.xm_offset = 0; 987 xm.xm_offset = 0;
989 988
@@ -1001,61 +1000,59 @@ ncr53c9x_update_xfer_mode(struct ncr53c9 @@ -1001,61 +1000,59 @@ ncr53c9x_update_xfer_mode(struct ncr53c9
1001 scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm); 1000 scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm);
1002} 1001}
1003 1002
1004/* 1003/*
1005 * Used when interrupt driven I/O isn't allowed, e.g. during boot. 1004 * Used when interrupt driven I/O isn't allowed, e.g. during boot.
1006 */ 1005 */
1007int 1006int
1008ncr53c9x_poll(struct ncr53c9x_softc *sc, struct scsipi_xfer *xs, int count) 1007ncr53c9x_poll(struct ncr53c9x_softc *sc, struct scsipi_xfer *xs, int count)
1009{ 1008{
1010 1009
1011 NCR_TRACE(("[ncr53c9x_poll] ")); 1010 NCR_TRACE(("[ncr53c9x_poll] "));
1012 while (count) { 1011 while (count) {
1013 if (NCRDMA_ISINTR(sc)) { 1012 if (NCRDMA_ISINTR(sc)) {
1014 simple_unlock(&sc->sc_lock); 1013 mutex_exit(&sc->sc_lock);
1015 ncr53c9x_intr(sc); 1014 ncr53c9x_intr(sc);
1016 simple_lock(&sc->sc_lock); 1015 mutex_enter(&sc->sc_lock);
1017 } 1016 }
1018#if alternatively 1017#if alternatively
1019 if (NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT) 1018 if (NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT)
1020 ncr53c9x_intr(sc); 1019 ncr53c9x_intr(sc);
1021#endif 1020#endif
1022 if ((xs->xs_status & XS_STS_DONE) != 0) 1021 if ((xs->xs_status & XS_STS_DONE) != 0)
1023 return 0; 1022 return 0;
1024 if (sc->sc_state == NCR_IDLE) { 1023 if (sc->sc_state == NCR_IDLE) {
1025 NCR_TRACE(("[ncr53c9x_poll: rescheduling] ")); 1024 NCR_TRACE(("[ncr53c9x_poll: rescheduling] "));
1026 ncr53c9x_sched(sc); 1025 ncr53c9x_sched(sc);
1027 } 1026 }
1028 DELAY(1000); 1027 DELAY(1000);
1029 count--; 1028 count--;
1030 } 1029 }
1031 return 1; 1030 return 1;
1032} 1031}
1033 1032
1034int 1033int
1035ncr53c9x_ioctl(struct scsipi_channel *chan, u_long cmd, void *arg, 1034ncr53c9x_ioctl(struct scsipi_channel *chan, u_long cmd, void *arg,
1036 int flag, struct proc *p) 1035 int flag, struct proc *p)
1037{ 1036{
1038 struct ncr53c9x_softc *sc; 1037 struct ncr53c9x_softc *sc;
1039 int s, error = 0; 1038 int error = 0;
1040 1039
1041 sc = device_private(chan->chan_adapter->adapt_dev); 1040 sc = device_private(chan->chan_adapter->adapt_dev);
1042 switch (cmd) { 1041 switch (cmd) {
1043 case SCBUSIORESET: 1042 case SCBUSIORESET:
1044 s = splbio(); 1043 mutex_enter(&sc->sc_lock);
1045 simple_lock(&sc->sc_lock); 
1046 ncr53c9x_init(sc, 1); 1044 ncr53c9x_init(sc, 1);
1047 simple_unlock(&sc->sc_lock); 1045 mutex_exit(&sc->sc_lock);
1048 splx(s); 
1049 break; 1046 break;
1050 default: 1047 default:
1051 error = ENOTTY; 1048 error = ENOTTY;
1052 break; 1049 break;
1053 } 1050 }
1054 return error; 1051 return error;
1055} 1052}
1056 1053
1057 1054
1058/* 1055/*
1059 * LOW LEVEL SCSI UTILITIES 1056 * LOW LEVEL SCSI UTILITIES
1060 */ 1057 */
1061 1058
@@ -1269,29 +1266,29 @@ ncr53c9x_done(struct ncr53c9x_softc *sc, @@ -1269,29 +1266,29 @@ ncr53c9x_done(struct ncr53c9x_softc *sc,
1269 1266
1270 if (xs->error == XS_SELTIMEOUT) { 1267 if (xs->error == XS_SELTIMEOUT) {
1271 /* Selection timeout -- discard this LUN if empty */ 1268 /* Selection timeout -- discard this LUN if empty */
1272 if (li->untagged == NULL && li->used == 0) { 1269 if (li->untagged == NULL && li->used == 0) {
1273 if (lun < NCR_NLUN) 1270 if (lun < NCR_NLUN)
1274 ti->lun[lun] = NULL; 1271 ti->lun[lun] = NULL;
1275 LIST_REMOVE(li, link); 1272 LIST_REMOVE(li, link);
1276 free(li, M_DEVBUF); 1273 free(li, M_DEVBUF);
1277 } 1274 }
1278 } 1275 }
1279 1276
1280 ncr53c9x_free_ecb(sc, ecb); 1277 ncr53c9x_free_ecb(sc, ecb);
1281 ti->cmds++; 1278 ti->cmds++;
1282 simple_unlock(&sc->sc_lock); 1279 mutex_exit(&sc->sc_lock);
1283 scsipi_done(xs); 1280 scsipi_done(xs);
1284 simple_lock(&sc->sc_lock); 1281 mutex_enter(&sc->sc_lock);
1285} 1282}
1286 1283
1287void 1284void
1288ncr53c9x_dequeue(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb) 1285ncr53c9x_dequeue(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
1289{ 1286{
1290 struct ncr53c9x_tinfo *ti = 1287 struct ncr53c9x_tinfo *ti =
1291 &sc->sc_tinfo[ecb->xs->xs_periph->periph_target]; 1288 &sc->sc_tinfo[ecb->xs->xs_periph->periph_target];
1292 struct ncr53c9x_linfo *li; 1289 struct ncr53c9x_linfo *li;
1293 int64_t lun = ecb->xs->xs_periph->periph_lun; 1290 int64_t lun = ecb->xs->xs_periph->periph_lun;
1294 1291
1295 li = TINFO_LUN(ti, lun); 1292 li = TINFO_LUN(ti, lun);
1296#ifdef DIAGNOSTIC 1293#ifdef DIAGNOSTIC
1297 if (li == NULL || li->lun != lun) 1294 if (li == NULL || li->lun != lun)
@@ -2080,27 +2077,27 @@ ncr53c9x_intr(void *arg) @@ -2080,27 +2077,27 @@ ncr53c9x_intr(void *arg)
2080{ 2077{
2081 struct ncr53c9x_softc *sc = arg; 2078 struct ncr53c9x_softc *sc = arg;
2082 struct ncr53c9x_ecb *ecb; 2079 struct ncr53c9x_ecb *ecb;
2083 struct scsipi_periph *periph; 2080 struct scsipi_periph *periph;
2084 struct ncr53c9x_tinfo *ti; 2081 struct ncr53c9x_tinfo *ti;
2085 size_t size; 2082 size_t size;
2086 int nfifo; 2083 int nfifo;
2087 2084
2088 NCR_INTS(("[ncr53c9x_intr: state %d]", sc->sc_state)); 2085 NCR_INTS(("[ncr53c9x_intr: state %d]", sc->sc_state));
2089 2086
2090 if (!NCRDMA_ISINTR(sc)) 2087 if (!NCRDMA_ISINTR(sc))
2091 return 0; 2088 return 0;
2092 2089
2093 simple_lock(&sc->sc_lock); 2090 mutex_enter(&sc->sc_lock);
2094again: 2091again:
2095 /* and what do the registers say... */ 2092 /* and what do the registers say... */
2096 ncr53c9x_readregs(sc); 2093 ncr53c9x_readregs(sc);
2097 2094
2098 sc->sc_intrcnt.ev_count++; 2095 sc->sc_intrcnt.ev_count++;
2099 2096
2100 /* 2097 /*
2101 * At the moment, only a SCSI Bus Reset or Illegal 2098 * At the moment, only a SCSI Bus Reset or Illegal
2102 * Command are classed as errors. A disconnect is a 2099 * Command are classed as errors. A disconnect is a
2103 * valid condition, and we let the code check is the 2100 * valid condition, and we let the code check is the
2104 * "NCR_BUSFREE_OK" flag was set before declaring it 2101 * "NCR_BUSFREE_OK" flag was set before declaring it
2105 * and error. 2102 * and error.
2106 * 2103 *
@@ -2614,27 +2611,27 @@ again: @@ -2614,27 +2611,27 @@ again:
2614 } else { 2611 } else {
2615 2612
2616 printf("%s: unexpected status after select" 2613 printf("%s: unexpected status after select"
2617 ": [intr %x, stat %x, step %x]\n", 2614 ": [intr %x, stat %x, step %x]\n",
2618 device_xname(sc->sc_dev), 2615 device_xname(sc->sc_dev),
2619 sc->sc_espintr, sc->sc_espstat, sc->sc_espstep); 2616 sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
2620 NCRCMD(sc, NCRCMD_FLUSH); 2617 NCRCMD(sc, NCRCMD_FLUSH);
2621 DELAY(1); 2618 DELAY(1);
2622 goto reset; 2619 goto reset;
2623 } 2620 }
2624 if (sc->sc_state == NCR_IDLE) { 2621 if (sc->sc_state == NCR_IDLE) {
2625 printf("%s: stray interrupt\n", 2622 printf("%s: stray interrupt\n",
2626 device_xname(sc->sc_dev)); 2623 device_xname(sc->sc_dev));
2627 simple_unlock(&sc->sc_lock); 2624 mutex_exit(&sc->sc_lock);
2628 return 0; 2625 return 0;
2629 } 2626 }
2630 break; 2627 break;
2631 2628
2632 case NCR_CONNECTED: 2629 case NCR_CONNECTED:
2633 if ((sc->sc_flags & NCR_ICCS) != 0) { 2630 if ((sc->sc_flags & NCR_ICCS) != 0) {
2634 /* "Initiate Command Complete Steps" in progress */ 2631 /* "Initiate Command Complete Steps" in progress */
2635 uint8_t msg; 2632 uint8_t msg;
2636 2633
2637 sc->sc_flags &= ~NCR_ICCS; 2634 sc->sc_flags &= ~NCR_ICCS;
2638 2635
2639 if ((sc->sc_espintr & NCRINTR_DONE) == 0) { 2636 if ((sc->sc_espintr & NCRINTR_DONE) == 0) {
2640 printf("%s: ICCS: " 2637 printf("%s: ICCS: "
@@ -2805,27 +2802,27 @@ msgin: @@ -2805,27 +2802,27 @@ msgin:
2805 sc->sc_prevphase = STATUS_PHASE; 2802 sc->sc_prevphase = STATUS_PHASE;
2806 goto shortcut; /* i.e. expect status results soon */ 2803 goto shortcut; /* i.e. expect status results soon */
2807 2804
2808 case INVALID_PHASE: 2805 case INVALID_PHASE:
2809 break; 2806 break;
2810 2807
2811 default: 2808 default:
2812 printf("%s: unexpected bus phase; resetting\n", 2809 printf("%s: unexpected bus phase; resetting\n",
2813 device_xname(sc->sc_dev)); 2810 device_xname(sc->sc_dev));
2814 goto reset; 2811 goto reset;
2815 } 2812 }
2816 2813
2817out: 2814out:
2818 simple_unlock(&sc->sc_lock); 2815 mutex_exit(&sc->sc_lock);
2819 return 1; 2816 return 1;
2820 2817
2821reset: 2818reset:
2822 ncr53c9x_init(sc, 1); 2819 ncr53c9x_init(sc, 1);
2823 goto out; 2820 goto out;
2824 2821
2825finish: 2822finish:
2826 ncr53c9x_done(sc, ecb); 2823 ncr53c9x_done(sc, ecb);
2827 goto out; 2824 goto out;
2828 2825
2829sched: 2826sched:
2830 sc->sc_state = NCR_IDLE; 2827 sc->sc_state = NCR_IDLE;
2831 ncr53c9x_sched(sc); 2828 ncr53c9x_sched(sc);
@@ -2889,98 +2886,93 @@ ncr53c9x_abort(struct ncr53c9x_softc *sc @@ -2889,98 +2886,93 @@ ncr53c9x_abort(struct ncr53c9x_softc *sc
2889 if (sc->sc_state == NCR_IDLE) 2886 if (sc->sc_state == NCR_IDLE)
2890 ncr53c9x_sched(sc); 2887 ncr53c9x_sched(sc);
2891 } 2888 }
2892} 2889}
2893 2890
2894void 2891void
2895ncr53c9x_timeout(void *arg) 2892ncr53c9x_timeout(void *arg)
2896{ 2893{
2897 struct ncr53c9x_ecb *ecb = arg; 2894 struct ncr53c9x_ecb *ecb = arg;
2898 struct scsipi_xfer *xs = ecb->xs; 2895 struct scsipi_xfer *xs = ecb->xs;
2899 struct scsipi_periph *periph = xs->xs_periph; 2896 struct scsipi_periph *periph = xs->xs_periph;
2900 struct ncr53c9x_softc *sc; 2897 struct ncr53c9x_softc *sc;
2901 struct ncr53c9x_tinfo *ti; 2898 struct ncr53c9x_tinfo *ti;
2902 int s; 
2903 2899
2904 sc = device_private(periph->periph_channel->chan_adapter->adapt_dev); 2900 sc = device_private(periph->periph_channel->chan_adapter->adapt_dev);
2905 ti = &sc->sc_tinfo[periph->periph_target]; 2901 ti = &sc->sc_tinfo[periph->periph_target];
2906 2902
2907 scsipi_printaddr(periph); 2903 scsipi_printaddr(periph);
2908 printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], " 2904 printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
2909 "<state %d, nexus %p, phase(l %x, c %x, p %x), resid %lx, " 2905 "<state %d, nexus %p, phase(l %x, c %x, p %x), resid %lx, "
2910 "msg(q %x,o %x) %s>", 2906 "msg(q %x,o %x) %s>",
2911 device_xname(sc->sc_dev), 2907 device_xname(sc->sc_dev),
2912 ecb, ecb->flags, ecb->dleft, ecb->stat, 2908 ecb, ecb->flags, ecb->dleft, ecb->stat,
2913 sc->sc_state, sc->sc_nexus, 2909 sc->sc_state, sc->sc_nexus,
2914 NCR_READ_REG(sc, NCR_STAT), 2910 NCR_READ_REG(sc, NCR_STAT),
2915 sc->sc_phase, sc->sc_prevphase, 2911 sc->sc_phase, sc->sc_prevphase,
2916 (long)sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout, 2912 (long)sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
2917 NCRDMA_ISACTIVE(sc) ? "DMA active" : ""); 2913 NCRDMA_ISACTIVE(sc) ? "DMA active" : "");
2918#if NCR53C9X_DEBUG > 1 2914#if NCR53C9X_DEBUG > 1
2919 printf("TRACE: %s.", ecb->trace); 2915 printf("TRACE: %s.", ecb->trace);
2920#endif 2916#endif
2921 2917
2922 s = splbio(); 2918 mutex_enter(&sc->sc_lock);
2923 simple_lock(&sc->sc_lock); 
2924 2919
2925 if (ecb->flags & ECB_ABORT) { 2920 if (ecb->flags & ECB_ABORT) {
2926 /* abort timed out */ 2921 /* abort timed out */
2927 printf(" AGAIN\n"); 2922 printf(" AGAIN\n");
2928 2923
2929 ncr53c9x_init(sc, 1); 2924 ncr53c9x_init(sc, 1);
2930 } else { 2925 } else {
2931 /* abort the operation that has timed out */ 2926 /* abort the operation that has timed out */
2932 printf("\n"); 2927 printf("\n");
2933 xs->error = XS_TIMEOUT; 2928 xs->error = XS_TIMEOUT;
2934 ncr53c9x_abort(sc, ecb); 2929 ncr53c9x_abort(sc, ecb);
2935 2930
2936 /* Disable sync mode if stuck in a data phase */ 2931 /* Disable sync mode if stuck in a data phase */
2937 if (ecb == sc->sc_nexus && 2932 if (ecb == sc->sc_nexus &&
2938 (ti->flags & T_SYNCMODE) != 0 && 2933 (ti->flags & T_SYNCMODE) != 0 &&
2939 (sc->sc_phase & (MSGI | CDI)) == 0) { 2934 (sc->sc_phase & (MSGI | CDI)) == 0) {
2940 /* XXX ASYNC CALLBACK! */ 2935 /* XXX ASYNC CALLBACK! */
2941 scsipi_printaddr(periph); 2936 scsipi_printaddr(periph);
2942 printf("sync negotiation disabled\n"); 2937 printf("sync negotiation disabled\n");
2943 sc->sc_cfflags |= 2938 sc->sc_cfflags |=
2944 (1 << ((periph->periph_target & 7) + 8)); 2939 (1 << ((periph->periph_target & 7) + 8));
2945 ncr53c9x_update_xfer_mode(sc, periph->periph_target); 2940 ncr53c9x_update_xfer_mode(sc, periph->periph_target);
2946 } 2941 }
2947 } 2942 }
2948 2943
2949 simple_unlock(&sc->sc_lock); 2944 mutex_exit(&sc->sc_lock);
2950 splx(s); 
2951} 2945}
2952 2946
2953void 2947void
2954ncr53c9x_watch(void *arg) 2948ncr53c9x_watch(void *arg)
2955{ 2949{
2956 struct ncr53c9x_softc *sc = arg; 2950 struct ncr53c9x_softc *sc = arg;
2957 struct ncr53c9x_tinfo *ti; 2951 struct ncr53c9x_tinfo *ti;
2958 struct ncr53c9x_linfo *li; 2952 struct ncr53c9x_linfo *li;
2959 int t, s; 2953 int t;
2960 /* Delete any structures that have not been used in 10min. */ 2954 /* Delete any structures that have not been used in 10min. */
2961 time_t old = time_second - (10 * 60); 2955 time_t old = time_second - (10 * 60);
2962 2956
2963 s = splbio(); 2957 mutex_enter(&sc->sc_lock);
2964 simple_lock(&sc->sc_lock); 
2965 for (t = 0; t < sc->sc_ntarg; t++) { 2958 for (t = 0; t < sc->sc_ntarg; t++) {
2966 ti = &sc->sc_tinfo[t]; 2959 ti = &sc->sc_tinfo[t];
2967 li = LIST_FIRST(&ti->luns); 2960 li = LIST_FIRST(&ti->luns);
2968 while (li) { 2961 while (li) {
2969 if (li->last_used < old && 2962 if (li->last_used < old &&
2970 li->untagged == NULL && 2963 li->untagged == NULL &&
2971 li->used == 0) { 2964 li->used == 0) {
2972 if (li->lun < NCR_NLUN) 2965 if (li->lun < NCR_NLUN)
2973 ti->lun[li->lun] = NULL; 2966 ti->lun[li->lun] = NULL;
2974 LIST_REMOVE(li, link); 2967 LIST_REMOVE(li, link);
2975 free(li, M_DEVBUF); 2968 free(li, M_DEVBUF);
2976 /* Restart the search at the beginning */ 2969 /* Restart the search at the beginning */
2977 li = LIST_FIRST(&ti->luns); 2970 li = LIST_FIRST(&ti->luns);
2978 continue; 2971 continue;
2979 } 2972 }
2980 li = LIST_NEXT(li, link); 2973 li = LIST_NEXT(li, link);
2981 } 2974 }
2982 } 2975 }
2983 simple_unlock(&sc->sc_lock); 2976 mutex_exit(&sc->sc_lock);
2984 splx(s); 
2985 callout_reset(&sc->sc_watchdog, 60 * hz, ncr53c9x_watch, sc); 2977 callout_reset(&sc->sc_watchdog, 60 * hz, ncr53c9x_watch, sc);
2986} 2978}

cvs diff -r1.54 -r1.55 src/sys/dev/ic/ncr53c9xvar.h (expand / switch to unified diff)

--- src/sys/dev/ic/ncr53c9xvar.h 2009/09/07 13:31:44 1.54
+++ src/sys/dev/ic/ncr53c9xvar.h 2011/07/31 18:39:00 1.55
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ncr53c9xvar.h,v 1.54 2009/09/07 13:31:44 tsutsui Exp $ */ 1/* $NetBSD: ncr53c9xvar.h,v 1.55 2011/07/31 18:39:00 jakllsch Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center. 9 * NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -52,27 +52,27 @@ @@ -52,27 +52,27 @@
52 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 53 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
54 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 54 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 56 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 57 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 58 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
59 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 */ 60 */
61 61
62#ifndef _DEV_IC_NCR53C9XVAR_H_ 62#ifndef _DEV_IC_NCR53C9XVAR_H_
63#define _DEV_IC_NCR53C9XVAR_H_ 63#define _DEV_IC_NCR53C9XVAR_H_
64 64
65#include <sys/simplelock.h> 65#include <sys/mutex.h>
66 66
67/* Set this to 1 for normal debug, or 2 for per-target tracing. */ 67/* Set this to 1 for normal debug, or 2 for per-target tracing. */
68/* #define NCR53C9X_DEBUG 1 */ 68/* #define NCR53C9X_DEBUG 1 */
69 69
70/* Wide or differential can have 16 targets */ 70/* Wide or differential can have 16 targets */
71#define NCR_NLUN 8 71#define NCR_NLUN 8
72 72
73#define NCR_ABORT_TIMEOUT 2000 /* time to wait for abort */ 73#define NCR_ABORT_TIMEOUT 2000 /* time to wait for abort */
74#define NCR_SENSE_TIMEOUT 1000 /* time to wait for sense */ 74#define NCR_SENSE_TIMEOUT 1000 /* time to wait for sense */
75 75
76#define FREQTOCCF(freq) (((freq + 4) / 5)) 76#define FREQTOCCF(freq) (((freq + 4) / 5))
77 77
78/* 78/*
@@ -325,27 +325,27 @@ struct ncr53c9x_softc { @@ -325,27 +325,27 @@ struct ncr53c9x_softc {
325 size_t sc_imlen; 325 size_t sc_imlen;
326 326
327 uint8_t *sc_cmdp; /* Command pointer (for DMAed commands) */ 327 uint8_t *sc_cmdp; /* Command pointer (for DMAed commands) */
328 size_t sc_cmdlen; /* Size of command in transit */ 328 size_t sc_cmdlen; /* Size of command in transit */
329 329
330 /* Hardware attributes */ 330 /* Hardware attributes */
331 int sc_freq; /* SCSI bus frequency in MHz */ 331 int sc_freq; /* SCSI bus frequency in MHz */
332 int sc_id; /* Our SCSI id */ 332 int sc_id; /* Our SCSI id */
333 int sc_rev; /* Chip revision */ 333 int sc_rev; /* Chip revision */
334 int sc_features; /* Chip features */ 334 int sc_features; /* Chip features */
335 int sc_minsync; /* Minimum sync period / 4 */ 335 int sc_minsync; /* Minimum sync period / 4 */
336 int sc_maxxfer; /* Maximum transfer size */ 336 int sc_maxxfer; /* Maximum transfer size */
337 337
338 struct simplelock sc_lock;/* driver mutex */ 338 kmutex_t sc_lock; /* driver mutex */
339}; 339};
340 340
341/* values for sc_state */ 341/* values for sc_state */
342#define NCR_IDLE 1 /* waiting for something to do */ 342#define NCR_IDLE 1 /* waiting for something to do */
343#define NCR_SELECTING 2 /* SCSI command is arbiting */ 343#define NCR_SELECTING 2 /* SCSI command is arbiting */
344#define NCR_RESELECTED 3 /* Has been reselected */ 344#define NCR_RESELECTED 3 /* Has been reselected */
345#define NCR_IDENTIFIED 4 /* Has gotten IFY but not TAG */ 345#define NCR_IDENTIFIED 4 /* Has gotten IFY but not TAG */
346#define NCR_CONNECTED 5 /* Actively using the SCSI bus */ 346#define NCR_CONNECTED 5 /* Actively using the SCSI bus */
347#define NCR_DISCONNECT 6 /* MSG_DISCONNECT received */ 347#define NCR_DISCONNECT 6 /* MSG_DISCONNECT received */
348#define NCR_CMDCOMPLETE 7 /* MSG_CMDCOMPLETE received */ 348#define NCR_CMDCOMPLETE 7 /* MSG_CMDCOMPLETE received */
349#define NCR_CLEANING 8 349#define NCR_CLEANING 8
350#define NCR_SBR 9 /* Expect a SCSI RST because we commanded it */ 350#define NCR_SBR 9 /* Expect a SCSI RST because we commanded it */
351 351