aic.c (192066) | aic.c (241591) |
---|---|
1/*- 2 * Copyright (c) 1999 Luoqi Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1999 Luoqi Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/aic/aic.c 192066 2009-05-13 22:31:25Z des $"); | 28__FBSDID("$FreeBSD: head/sys/dev/aic/aic.c 241591 2012-10-15 16:09:59Z jhb $"); |
29 30#include <sys/param.h> | 29 30#include <sys/param.h> |
31#include <sys/conf.h> |
|
31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/lock.h> 34#include <sys/mutex.h> 35#include <sys/malloc.h> 36#include <sys/bus.h> 37 38#include <machine/bus.h> | 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/lock.h> 35#include <sys/mutex.h> 36#include <sys/malloc.h> 37#include <sys/bus.h> 38 39#include <machine/bus.h> |
40#include <sys/rman.h> |
|
39 40#include <cam/cam.h> 41#include <cam/cam_ccb.h> 42#include <cam/cam_sim.h> 43#include <cam/cam_xpt_sim.h> 44#include <cam/cam_debug.h> 45 46#include <cam/scsi/scsi_message.h> 47 48#include <dev/aic/aic6360reg.h> 49#include <dev/aic/aicvar.h> 50 51static void aic_action(struct cam_sim *sim, union ccb *ccb); 52static void aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, 53 int nseg, int error); | 41 42#include <cam/cam.h> 43#include <cam/cam_ccb.h> 44#include <cam/cam_sim.h> 45#include <cam/cam_xpt_sim.h> 46#include <cam/cam_debug.h> 47 48#include <cam/scsi/scsi_message.h> 49 50#include <dev/aic/aic6360reg.h> 51#include <dev/aic/aicvar.h> 52 53static void aic_action(struct cam_sim *sim, union ccb *ccb); 54static void aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, 55 int nseg, int error); |
56static void aic_intr_locked(struct aic_softc *aic); |
|
54static void aic_start(struct aic_softc *aic); 55static void aic_select(struct aic_softc *aic); 56static void aic_selected(struct aic_softc *aic); 57static void aic_reselected(struct aic_softc *aic); 58static void aic_reconnect(struct aic_softc *aic, int tag); 59static void aic_cmd(struct aic_softc *aic); 60static void aic_msgin(struct aic_softc *aic); 61static void aic_handle_msgin(struct aic_softc *aic); --- 4 unchanged lines hidden (view full) --- 66static void aic_poll(struct cam_sim *sim); 67static void aic_timeout(void *arg); 68static void aic_scsi_reset(struct aic_softc *aic); 69static void aic_chip_reset(struct aic_softc *aic); 70static void aic_reset(struct aic_softc *aic, int initiate_reset); 71 72devclass_t aic_devclass; 73 | 57static void aic_start(struct aic_softc *aic); 58static void aic_select(struct aic_softc *aic); 59static void aic_selected(struct aic_softc *aic); 60static void aic_reselected(struct aic_softc *aic); 61static void aic_reconnect(struct aic_softc *aic, int tag); 62static void aic_cmd(struct aic_softc *aic); 63static void aic_msgin(struct aic_softc *aic); 64static void aic_handle_msgin(struct aic_softc *aic); --- 4 unchanged lines hidden (view full) --- 69static void aic_poll(struct cam_sim *sim); 70static void aic_timeout(void *arg); 71static void aic_scsi_reset(struct aic_softc *aic); 72static void aic_chip_reset(struct aic_softc *aic); 73static void aic_reset(struct aic_softc *aic, int initiate_reset); 74 75devclass_t aic_devclass; 76 |
74static struct aic_scb *free_scbs; 75 | |
76static struct aic_scb * 77aic_get_scb(struct aic_softc *aic) 78{ 79 struct aic_scb *scb; | 77static struct aic_scb * 78aic_get_scb(struct aic_softc *aic) 79{ 80 struct aic_scb *scb; |
80 int s = splcam(); 81 if ((scb = free_scbs) != NULL) 82 free_scbs = (struct aic_scb *)free_scbs->ccb; 83 splx(s); | 81 82 if (!dumping) 83 mtx_assert(&aic->lock, MA_OWNED); 84 if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL) 85 SLIST_REMOVE_HEAD(&aic->free_scbs, link); |
84 return (scb); 85} 86 87static void 88aic_free_scb(struct aic_softc *aic, struct aic_scb *scb) 89{ | 86 return (scb); 87} 88 89static void 90aic_free_scb(struct aic_softc *aic, struct aic_scb *scb) 91{ |
90 int s = splcam(); | 92 93 if (!dumping) 94 mtx_assert(&aic->lock, MA_OWNED); |
91 if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 && 92 (scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 93 scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 94 aic->flags &= ~AIC_RESOURCE_SHORTAGE; 95 } 96 scb->flags = 0; | 95 if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 && 96 (scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 97 scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 98 aic->flags &= ~AIC_RESOURCE_SHORTAGE; 99 } 100 scb->flags = 0; |
97 scb->ccb = (union ccb *)free_scbs; 98 free_scbs = scb; 99 splx(s); | 101 SLIST_INSERT_HEAD(&aic->free_scbs, scb, link); |
100} 101 102static void 103aic_action(struct cam_sim *sim, union ccb *ccb) 104{ 105 struct aic_softc *aic; | 102} 103 104static void 105aic_action(struct cam_sim *sim, union ccb *ccb) 106{ 107 struct aic_softc *aic; |
106 int s; | |
107 108 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n")); 109 110 aic = (struct aic_softc *)cam_sim_softc(sim); | 108 109 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n")); 110 111 aic = (struct aic_softc *)cam_sim_softc(sim); |
112 mtx_assert(&aic->lock, MA_OWNED); |
|
111 112 switch (ccb->ccb_h.func_code) { 113 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 114 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 115 { 116 struct aic_scb *scb; 117 118 if ((scb = aic_get_scb(aic)) == NULL) { | 113 114 switch (ccb->ccb_h.func_code) { 115 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 116 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 117 { 118 struct aic_scb *scb; 119 120 if ((scb = aic_get_scb(aic)) == NULL) { |
119 s = splcam(); | |
120 aic->flags |= AIC_RESOURCE_SHORTAGE; | 121 aic->flags |= AIC_RESOURCE_SHORTAGE; |
121 splx(s); | |
122 xpt_freeze_simq(aic->sim, /*count*/1); 123 ccb->ccb_h.status = CAM_REQUEUE_REQ; 124 xpt_done(ccb); 125 return; 126 } 127 128 scb->ccb = ccb; 129 ccb->ccb_h.ccb_scb_ptr = scb; --- 40 unchanged lines hidden (view full) --- 170 { 171 struct ccb_trans_settings *cts = &ccb->cts; 172 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; 173 struct ccb_trans_settings_scsi *scsi = 174 &cts->proto_specific.scsi; 175 struct ccb_trans_settings_spi *spi = 176 &cts->xport_specific.spi; 177 | 122 xpt_freeze_simq(aic->sim, /*count*/1); 123 ccb->ccb_h.status = CAM_REQUEUE_REQ; 124 xpt_done(ccb); 125 return; 126 } 127 128 scb->ccb = ccb; 129 ccb->ccb_h.ccb_scb_ptr = scb; --- 40 unchanged lines hidden (view full) --- 170 { 171 struct ccb_trans_settings *cts = &ccb->cts; 172 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; 173 struct ccb_trans_settings_scsi *scsi = 174 &cts->proto_specific.scsi; 175 struct ccb_trans_settings_spi *spi = 176 &cts->xport_specific.spi; 177 |
178 s = splcam(); 179 | |
180 if ((spi->valid & CTS_SPI_VALID_DISC) != 0 && 181 (aic->flags & AIC_DISC_ENABLE) != 0) { 182 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 183 ti->flags |= TINFO_DISC_ENB; 184 else 185 ti->flags &= ~TINFO_DISC_ENB; 186 } 187 --- 21 unchanged lines hidden (view full) --- 209 else if (ti->goal.offset > AIC_SYNC_OFFSET) 210 ti->goal.offset = AIC_SYNC_OFFSET; 211 } 212 213 if ((ti->goal.period != ti->current.period) 214 || (ti->goal.offset != ti->current.offset)) 215 ti->flags |= TINFO_SDTR_NEGO; 216 | 178 if ((spi->valid & CTS_SPI_VALID_DISC) != 0 && 179 (aic->flags & AIC_DISC_ENABLE) != 0) { 180 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 181 ti->flags |= TINFO_DISC_ENB; 182 else 183 ti->flags &= ~TINFO_DISC_ENB; 184 } 185 --- 21 unchanged lines hidden (view full) --- 207 else if (ti->goal.offset > AIC_SYNC_OFFSET) 208 ti->goal.offset = AIC_SYNC_OFFSET; 209 } 210 211 if ((ti->goal.period != ti->current.period) 212 || (ti->goal.offset != ti->current.offset)) 213 ti->flags |= TINFO_SDTR_NEGO; 214 |
217 splx(s); | |
218 ccb->ccb_h.status = CAM_REQ_CMP; 219 xpt_done(ccb); 220 break; 221 } 222 case XPT_GET_TRAN_SETTINGS: 223 { 224 struct ccb_trans_settings *cts = &ccb->cts; 225 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; --- 4 unchanged lines hidden (view full) --- 230 231 cts->protocol = PROTO_SCSI; 232 cts->protocol_version = SCSI_REV_2; 233 cts->transport = XPORT_SPI; 234 cts->transport_version = 2; 235 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 236 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 237 | 215 ccb->ccb_h.status = CAM_REQ_CMP; 216 xpt_done(ccb); 217 break; 218 } 219 case XPT_GET_TRAN_SETTINGS: 220 { 221 struct ccb_trans_settings *cts = &ccb->cts; 222 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; --- 4 unchanged lines hidden (view full) --- 227 228 cts->protocol = PROTO_SCSI; 229 cts->protocol_version = SCSI_REV_2; 230 cts->transport = XPORT_SPI; 231 cts->transport_version = 2; 232 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 233 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 234 |
238 s = splcam(); | |
239 if ((ti->flags & TINFO_DISC_ENB) != 0) 240 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 241 if ((ti->flags & TINFO_TAG_ENB) != 0) 242 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 243 244 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 245 spi->sync_period = ti->current.period; 246 spi->sync_offset = ti->current.offset; 247 } else { 248 spi->sync_period = ti->user.period; 249 spi->sync_offset = ti->user.offset; 250 } | 235 if ((ti->flags & TINFO_DISC_ENB) != 0) 236 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 237 if ((ti->flags & TINFO_TAG_ENB) != 0) 238 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 239 240 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 241 spi->sync_period = ti->current.period; 242 spi->sync_offset = ti->current.offset; 243 } else { 244 spi->sync_period = ti->user.period; 245 spi->sync_offset = ti->user.offset; 246 } |
251 splx(s); | |
252 253 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 254 spi->valid = CTS_SPI_VALID_SYNC_RATE 255 | CTS_SPI_VALID_SYNC_OFFSET 256 | CTS_SPI_VALID_BUS_WIDTH 257 | CTS_SPI_VALID_DISC; 258 scsi->valid = CTS_SCSI_VALID_TQ; 259 --- 46 unchanged lines hidden (view full) --- 306} 307 308static void 309aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 310{ 311 struct aic_scb *scb = (struct aic_scb *)arg; 312 union ccb *ccb = scb->ccb; 313 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; | 247 248 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 249 spi->valid = CTS_SPI_VALID_SYNC_RATE 250 | CTS_SPI_VALID_SYNC_OFFSET 251 | CTS_SPI_VALID_BUS_WIDTH 252 | CTS_SPI_VALID_DISC; 253 scsi->valid = CTS_SCSI_VALID_TQ; 254 --- 46 unchanged lines hidden (view full) --- 301} 302 303static void 304aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 305{ 306 struct aic_scb *scb = (struct aic_scb *)arg; 307 union ccb *ccb = scb->ccb; 308 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; |
314 int s; | |
315 | 309 |
316 s = splcam(); 317 | 310 if (!dumping) 311 mtx_assert(&aic->lock, MA_OWNED); |
318 if (ccb->ccb_h.status != CAM_REQ_INPROG) { | 312 if (ccb->ccb_h.status != CAM_REQ_INPROG) { |
319 splx(s); | |
320 aic_free_scb(aic, scb); 321 xpt_done(ccb); 322 return; 323 } 324 325 scb->flags |= SCB_ACTIVE; 326 ccb->ccb_h.status |= CAM_SIM_QUEUED; 327 TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe); 328 | 313 aic_free_scb(aic, scb); 314 xpt_done(ccb); 315 return; 316 } 317 318 scb->flags |= SCB_ACTIVE; 319 ccb->ccb_h.status |= CAM_SIM_QUEUED; 320 TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe); 321 |
329 ccb->ccb_h.timeout_ch = timeout(aic_timeout, (caddr_t)scb, 330 (ccb->ccb_h.timeout * hz) / 1000); | 322 callout_reset(&scb->timer, (ccb->ccb_h.timeout * hz) / 1000, 323 aic_timeout, scb); |
331 332 aic_start(aic); | 324 325 aic_start(aic); |
333 splx(s); | |
334} 335 336/* 337 * Start another command if the controller is not busy. 338 */ 339static void 340aic_start(struct aic_softc *aic) 341{ --- 706 unchanged lines hidden (view full) --- 1048aic_done(struct aic_softc *aic, struct aic_scb *scb) 1049{ 1050 union ccb *ccb = scb->ccb; 1051 1052 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 1053 ("aic_done - ccb %p status %x resid %d\n", 1054 ccb, ccb->ccb_h.status, ccb->csio.resid)); 1055 | 326} 327 328/* 329 * Start another command if the controller is not busy. 330 */ 331static void 332aic_start(struct aic_softc *aic) 333{ --- 706 unchanged lines hidden (view full) --- 1040aic_done(struct aic_softc *aic, struct aic_scb *scb) 1041{ 1042 union ccb *ccb = scb->ccb; 1043 1044 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 1045 ("aic_done - ccb %p status %x resid %d\n", 1046 ccb, ccb->ccb_h.status, ccb->csio.resid)); 1047 |
1056 untimeout(aic_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch); | 1048 callout_stop(&scb->timer); |
1057 1058 if ((scb->flags & SCB_DEVICE_RESET) != 0 && 1059 ccb->ccb_h.func_code != XPT_RESET_DEV) { 1060 struct cam_path *path; 1061 struct ccb_hdr *ccb_h; 1062 cam_status error; 1063 1064 error = xpt_create_path(&path, /*periph*/NULL, --- 13 unchanged lines hidden (view full) --- 1078 pending_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 1079 if (ccb_h->target_id == scb->target) { 1080 ccb_h->status |= CAM_BDR_SENT; 1081 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1082 TAILQ_REMOVE(&aic->pending_ccbs, 1083 &pending_scb->ccb->ccb_h, sim_links.tqe); 1084 aic_done(aic, pending_scb); 1085 } else { | 1049 1050 if ((scb->flags & SCB_DEVICE_RESET) != 0 && 1051 ccb->ccb_h.func_code != XPT_RESET_DEV) { 1052 struct cam_path *path; 1053 struct ccb_hdr *ccb_h; 1054 cam_status error; 1055 1056 error = xpt_create_path(&path, /*periph*/NULL, --- 13 unchanged lines hidden (view full) --- 1070 pending_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 1071 if (ccb_h->target_id == scb->target) { 1072 ccb_h->status |= CAM_BDR_SENT; 1073 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1074 TAILQ_REMOVE(&aic->pending_ccbs, 1075 &pending_scb->ccb->ccb_h, sim_links.tqe); 1076 aic_done(aic, pending_scb); 1077 } else { |
1086 ccb_h->timeout_ch = 1087 timeout(aic_timeout, (caddr_t)pending_scb, 1088 (ccb_h->timeout * hz) / 1000); | 1078 callout_reset(&pending_scb->timer, 1079 (ccb_h->timeout * hz) / 1000, aic_timeout, 1080 pending_scb); |
1089 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1090 } 1091 } 1092 1093 ccb_h = TAILQ_FIRST(&aic->nexus_ccbs); 1094 while (ccb_h != NULL) { 1095 struct aic_scb *nexus_scb; 1096 1097 nexus_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 1098 if (ccb_h->target_id == scb->target) { 1099 ccb_h->status |= CAM_BDR_SENT; 1100 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1101 TAILQ_REMOVE(&aic->nexus_ccbs, 1102 &nexus_scb->ccb->ccb_h, sim_links.tqe); 1103 aic_done(aic, nexus_scb); 1104 } else { | 1081 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1082 } 1083 } 1084 1085 ccb_h = TAILQ_FIRST(&aic->nexus_ccbs); 1086 while (ccb_h != NULL) { 1087 struct aic_scb *nexus_scb; 1088 1089 nexus_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 1090 if (ccb_h->target_id == scb->target) { 1091 ccb_h->status |= CAM_BDR_SENT; 1092 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1093 TAILQ_REMOVE(&aic->nexus_ccbs, 1094 &nexus_scb->ccb->ccb_h, sim_links.tqe); 1095 aic_done(aic, nexus_scb); 1096 } else { |
1105 ccb_h->timeout_ch = 1106 timeout(aic_timeout, (caddr_t)nexus_scb, 1107 (ccb_h->timeout * hz) / 1000); | 1097 callout_reset(&nexus_scb->timer, 1098 (ccb_h->timeout * hz) / 1000, aic_timeout, 1099 nexus_scb); |
1108 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1109 } 1110 } 1111 } 1112 1113 if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED) 1114 aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun); 1115 1116 if (aic->nexus == scb) { 1117 aic->nexus = NULL; 1118 } 1119 aic_free_scb(aic, scb); 1120 xpt_done(ccb); 1121} 1122 1123static void 1124aic_poll(struct cam_sim *sim) 1125{ | 1100 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1101 } 1102 } 1103 } 1104 1105 if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED) 1106 aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun); 1107 1108 if (aic->nexus == scb) { 1109 aic->nexus = NULL; 1110 } 1111 aic_free_scb(aic, scb); 1112 xpt_done(ccb); 1113} 1114 1115static void 1116aic_poll(struct cam_sim *sim) 1117{ |
1126 aic_intr(cam_sim_softc(sim)); | 1118 aic_intr_locked(cam_sim_softc(sim)); |
1127} 1128 1129static void 1130aic_timeout(void *arg) 1131{ 1132 struct aic_scb *scb = (struct aic_scb *)arg; 1133 union ccb *ccb = scb->ccb; 1134 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; | 1119} 1120 1121static void 1122aic_timeout(void *arg) 1123{ 1124 struct aic_scb *scb = (struct aic_scb *)arg; 1125 union ccb *ccb = scb->ccb; 1126 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; |
1135 int s; | |
1136 | 1127 |
1128 mtx_assert(&aic->lock, MA_OWNED); |
|
1137 xpt_print_path(ccb->ccb_h.path); 1138 printf("ccb %p - timed out", ccb); 1139 if (aic->nexus && aic->nexus != scb) 1140 printf(", nexus %p", aic->nexus->ccb); 1141 printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state); 1142 | 1129 xpt_print_path(ccb->ccb_h.path); 1130 printf("ccb %p - timed out", ccb); 1131 if (aic->nexus && aic->nexus != scb) 1132 printf(", nexus %p", aic->nexus->ccb); 1133 printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state); 1134 |
1143 s = splcam(); 1144 | |
1145 if ((scb->flags & SCB_ACTIVE) == 0) { | 1135 if ((scb->flags & SCB_ACTIVE) == 0) { |
1146 splx(s); | |
1147 xpt_print_path(ccb->ccb_h.path); 1148 printf("ccb %p - timed out already completed\n", ccb); 1149 return; 1150 } 1151 1152 if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) { 1153 struct ccb_hdr *ccb_h = &scb->ccb->ccb_h; | 1136 xpt_print_path(ccb->ccb_h.path); 1137 printf("ccb %p - timed out already completed\n", ccb); 1138 return; 1139 } 1140 1141 if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) { 1142 struct ccb_hdr *ccb_h = &scb->ccb->ccb_h; |
1143 struct aic_scb *pending_scb; |
|
1154 1155 if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) { 1156 xpt_freeze_simq(aic->sim, /*count*/1); 1157 ccb_h->status |= CAM_RELEASE_SIMQ; 1158 } 1159 1160 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { | 1144 1145 if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) { 1146 xpt_freeze_simq(aic->sim, /*count*/1); 1147 ccb_h->status |= CAM_RELEASE_SIMQ; 1148 } 1149 1150 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { |
1161 untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr, 1162 ccb_h->timeout_ch); | 1151 pending_scb = ccb_h->ccb_scb_ptr; 1152 callout_stop(&pending_scb->timer); |
1163 } 1164 1165 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { | 1153 } 1154 1155 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { |
1166 untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr, 1167 ccb_h->timeout_ch); | 1156 pending_scb = ccb_h->ccb_scb_ptr; 1157 callout_stop(&pending_scb->timer); |
1168 } 1169 1170 scb->flags |= SCB_DEVICE_RESET; | 1158 } 1159 1160 scb->flags |= SCB_DEVICE_RESET; |
1171 ccb->ccb_h.timeout_ch = 1172 timeout(aic_timeout, (caddr_t)scb, 5 * hz); | 1161 callout_reset(&scb->timer, 5 * hz, aic_timeout, scb); |
1173 aic_sched_msgout(aic, MSG_BUS_DEV_RESET); 1174 } else { 1175 if (aic->nexus == scb) { 1176 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1177 aic_done(aic, scb); 1178 } 1179 aic_reset(aic, /*initiate_reset*/TRUE); 1180 } | 1162 aic_sched_msgout(aic, MSG_BUS_DEV_RESET); 1163 } else { 1164 if (aic->nexus == scb) { 1165 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1166 aic_done(aic, scb); 1167 } 1168 aic_reset(aic, /*initiate_reset*/TRUE); 1169 } |
1181 1182 splx(s); | |
1183} 1184 1185void 1186aic_intr(void *arg) 1187{ 1188 struct aic_softc *aic = (struct aic_softc *)arg; | 1170} 1171 1172void 1173aic_intr(void *arg) 1174{ 1175 struct aic_softc *aic = (struct aic_softc *)arg; |
1176 1177 mtx_lock(&aic->lock); 1178 aic_intr_locked(aic); 1179 mtx_unlock(&aic->lock); 1180} 1181 1182void 1183aic_intr_locked(struct aic_softc *aic) 1184{ |
|
1189 u_int8_t sstat0, sstat1; 1190 union ccb *ccb; 1191 struct aic_scb *scb; 1192 1193 if (!(aic_inb(aic, DMASTAT) & INTSTAT)) 1194 return; 1195 1196 aic_outb(aic, DMACNTRL0, 0); --- 232 unchanged lines hidden (view full) --- 1429 struct aic_scb *scb; 1430 struct aic_tinfo *ti; 1431 u_int8_t porta, portb; 1432 char chip_id[33]; 1433 int i; 1434 1435 TAILQ_INIT(&aic->pending_ccbs); 1436 TAILQ_INIT(&aic->nexus_ccbs); | 1185 u_int8_t sstat0, sstat1; 1186 union ccb *ccb; 1187 struct aic_scb *scb; 1188 1189 if (!(aic_inb(aic, DMASTAT) & INTSTAT)) 1190 return; 1191 1192 aic_outb(aic, DMACNTRL0, 0); --- 232 unchanged lines hidden (view full) --- 1425 struct aic_scb *scb; 1426 struct aic_tinfo *ti; 1427 u_int8_t porta, portb; 1428 char chip_id[33]; 1429 int i; 1430 1431 TAILQ_INIT(&aic->pending_ccbs); 1432 TAILQ_INIT(&aic->nexus_ccbs); |
1433 SLIST_INIT(&aic->free_scbs); |
|
1437 aic->nexus = NULL; 1438 aic->state = AIC_IDLE; 1439 aic->prev_phase = -1; 1440 aic->flags = 0; 1441 1442 aic_chip_reset(aic); 1443 aic_scsi_reset(aic); 1444 --- 31 unchanged lines hidden (view full) --- 1476 } 1477 1478 if (aic->flags & AIC_FAST_ENABLE) 1479 aic->max_period = AIC_FAST_SYNC_PERIOD; 1480 else 1481 aic->max_period = AIC_SYNC_PERIOD; 1482 aic->min_period = AIC_MIN_SYNC_PERIOD; 1483 | 1434 aic->nexus = NULL; 1435 aic->state = AIC_IDLE; 1436 aic->prev_phase = -1; 1437 aic->flags = 0; 1438 1439 aic_chip_reset(aic); 1440 aic_scsi_reset(aic); 1441 --- 31 unchanged lines hidden (view full) --- 1473 } 1474 1475 if (aic->flags & AIC_FAST_ENABLE) 1476 aic->max_period = AIC_FAST_SYNC_PERIOD; 1477 else 1478 aic->max_period = AIC_SYNC_PERIOD; 1479 aic->min_period = AIC_MIN_SYNC_PERIOD; 1480 |
1484 free_scbs = NULL; | |
1485 for (i = 255; i >= 0; i--) { 1486 scb = &aic->scbs[i]; 1487 scb->tag = i; | 1481 for (i = 255; i >= 0; i--) { 1482 scb = &aic->scbs[i]; 1483 scb->tag = i; |
1484 callout_init_mtx(&scb->timer, &aic->lock, 0); |
|
1488 aic_free_scb(aic, scb); 1489 } 1490 1491 for (i = 0; i < 8; i++) { 1492 if (i == aic->initiator) 1493 continue; 1494 ti = &aic->tinfo[i]; 1495 bzero(ti, sizeof(*ti)); --- 42 unchanged lines hidden (view full) --- 1538 devq = cam_simq_alloc(256); 1539 if (devq == NULL) 1540 return (ENOMEM); 1541 1542 /* 1543 * Construct our SIM entry 1544 */ 1545 aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic, | 1485 aic_free_scb(aic, scb); 1486 } 1487 1488 for (i = 0; i < 8; i++) { 1489 if (i == aic->initiator) 1490 continue; 1491 ti = &aic->tinfo[i]; 1492 bzero(ti, sizeof(*ti)); --- 42 unchanged lines hidden (view full) --- 1535 devq = cam_simq_alloc(256); 1536 if (devq == NULL) 1537 return (ENOMEM); 1538 1539 /* 1540 * Construct our SIM entry 1541 */ 1542 aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic, |
1546 aic->unit, &Giant, 2, 256, devq); | 1543 device_get_unit(aic->dev), &aic->lock, 2, 256, devq); |
1547 if (aic->sim == NULL) { 1548 cam_simq_free(devq); 1549 return (ENOMEM); 1550 } 1551 | 1544 if (aic->sim == NULL) { 1545 cam_simq_free(devq); 1546 return (ENOMEM); 1547 } 1548 |
1549 mtx_lock(&aic->lock); |
|
1552 if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) { 1553 cam_sim_free(aic->sim, /*free_devq*/TRUE); | 1550 if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) { 1551 cam_sim_free(aic->sim, /*free_devq*/TRUE); |
1552 mtx_unlock(&aic->lock); |
|
1554 return (ENXIO); 1555 } 1556 1557 if (xpt_create_path(&aic->path, /*periph*/NULL, 1558 cam_sim_path(aic->sim), CAM_TARGET_WILDCARD, 1559 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1560 xpt_bus_deregister(cam_sim_path(aic->sim)); 1561 cam_sim_free(aic->sim, /*free_devq*/TRUE); | 1553 return (ENXIO); 1554 } 1555 1556 if (xpt_create_path(&aic->path, /*periph*/NULL, 1557 cam_sim_path(aic->sim), CAM_TARGET_WILDCARD, 1558 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1559 xpt_bus_deregister(cam_sim_path(aic->sim)); 1560 cam_sim_free(aic->sim, /*free_devq*/TRUE); |
1561 mtx_unlock(&aic->lock); |
|
1562 return (ENXIO); 1563 } 1564 1565 aic_init(aic); 1566 | 1562 return (ENXIO); 1563 } 1564 1565 aic_init(aic); 1566 |
1567 printf("aic%d: %s", aic->unit, aic_chip_names[aic->chip_type]); | 1567 device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]); |
1568 if (aic->flags & AIC_DMA_ENABLE) 1569 printf(", dma"); 1570 if (aic->flags & AIC_DISC_ENABLE) 1571 printf(", disconnection"); 1572 if (aic->flags & AIC_PARITY_ENABLE) 1573 printf(", parity check"); 1574 if (aic->flags & AIC_FAST_ENABLE) 1575 printf(", fast SCSI"); 1576 printf("\n"); | 1568 if (aic->flags & AIC_DMA_ENABLE) 1569 printf(", dma"); 1570 if (aic->flags & AIC_DISC_ENABLE) 1571 printf(", disconnection"); 1572 if (aic->flags & AIC_PARITY_ENABLE) 1573 printf(", parity check"); 1574 if (aic->flags & AIC_FAST_ENABLE) 1575 printf(", fast SCSI"); 1576 printf("\n"); |
1577 mtx_unlock(&aic->lock); |
|
1577 return (0); 1578} 1579 1580int 1581aic_detach(struct aic_softc *aic) 1582{ | 1578 return (0); 1579} 1580 1581int 1582aic_detach(struct aic_softc *aic) 1583{ |
1584 struct aic_scb *scb; 1585 int i; 1586 1587 mtx_lock(&aic->lock); |
|
1583 xpt_async(AC_LOST_DEVICE, aic->path, NULL); 1584 xpt_free_path(aic->path); 1585 xpt_bus_deregister(cam_sim_path(aic->sim)); 1586 cam_sim_free(aic->sim, /*free_devq*/TRUE); | 1588 xpt_async(AC_LOST_DEVICE, aic->path, NULL); 1589 xpt_free_path(aic->path); 1590 xpt_bus_deregister(cam_sim_path(aic->sim)); 1591 cam_sim_free(aic->sim, /*free_devq*/TRUE); |
1592 mtx_unlock(&aic->lock); 1593 for (i = 255; i >= 0; i--) { 1594 scb = &aic->scbs[i]; 1595 callout_drain(&scb->timer); 1596 } |
|
1587 return (0); 1588} | 1597 return (0); 1598} |