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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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); 62static void aic_msgout(struct aic_softc *aic); 63static void aic_datain(struct aic_softc *aic); 64static void aic_dataout(struct aic_softc *aic); 65static void aic_done(struct aic_softc *aic, struct aic_scb *scb); 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); 65static void aic_msgout(struct aic_softc *aic); 66static void aic_datain(struct aic_softc *aic); 67static void aic_dataout(struct aic_softc *aic); 68static void aic_done(struct aic_softc *aic, struct aic_scb *scb); 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; 130 ccb->ccb_h.ccb_aic_ptr = aic; 131 132 scb->target = ccb->ccb_h.target_id; 133 scb->lun = ccb->ccb_h.target_lun; 134 135 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 136 scb->cmd_len = ccb->csio.cdb_len; 137 if (ccb->ccb_h.flags & CAM_CDB_POINTER) { 138 if (ccb->ccb_h.flags & CAM_CDB_PHYS) { 139 ccb->ccb_h.status = CAM_REQ_INVALID; 140 aic_free_scb(aic, scb); 141 xpt_done(ccb); 142 return; 143 } 144 scb->cmd_ptr = ccb->csio.cdb_io.cdb_ptr; 145 } else { 146 scb->cmd_ptr = ccb->csio.cdb_io.cdb_bytes; 147 } 148 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 149 if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) || 150 (ccb->ccb_h.flags & CAM_DATA_PHYS)) { 151 ccb->ccb_h.status = CAM_REQ_INVALID; 152 aic_free_scb(aic, scb); 153 xpt_done(ccb); 154 return; 155 } 156 scb->data_ptr = ccb->csio.data_ptr; 157 scb->data_len = ccb->csio.dxfer_len; 158 } else { 159 scb->data_ptr = NULL; 160 scb->data_len = 0; 161 } 162 aic_execute_scb(scb, NULL, 0, 0); 163 } else { 164 scb->flags |= SCB_DEVICE_RESET; 165 aic_execute_scb(scb, NULL, 0, 0); 166 } 167 break; 168 } 169 case XPT_SET_TRAN_SETTINGS: 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; 130 ccb->ccb_h.ccb_aic_ptr = aic; 131 132 scb->target = ccb->ccb_h.target_id; 133 scb->lun = ccb->ccb_h.target_lun; 134 135 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 136 scb->cmd_len = ccb->csio.cdb_len; 137 if (ccb->ccb_h.flags & CAM_CDB_POINTER) { 138 if (ccb->ccb_h.flags & CAM_CDB_PHYS) { 139 ccb->ccb_h.status = CAM_REQ_INVALID; 140 aic_free_scb(aic, scb); 141 xpt_done(ccb); 142 return; 143 } 144 scb->cmd_ptr = ccb->csio.cdb_io.cdb_ptr; 145 } else { 146 scb->cmd_ptr = ccb->csio.cdb_io.cdb_bytes; 147 } 148 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 149 if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) || 150 (ccb->ccb_h.flags & CAM_DATA_PHYS)) { 151 ccb->ccb_h.status = CAM_REQ_INVALID; 152 aic_free_scb(aic, scb); 153 xpt_done(ccb); 154 return; 155 } 156 scb->data_ptr = ccb->csio.data_ptr; 157 scb->data_len = ccb->csio.dxfer_len; 158 } else { 159 scb->data_ptr = NULL; 160 scb->data_len = 0; 161 } 162 aic_execute_scb(scb, NULL, 0, 0); 163 } else { 164 scb->flags |= SCB_DEVICE_RESET; 165 aic_execute_scb(scb, NULL, 0, 0); 166 } 167 break; 168 } 169 case XPT_SET_TRAN_SETTINGS: 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 188 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 189 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 190 ti->flags |= TINFO_TAG_ENB; 191 else 192 ti->flags &= ~TINFO_TAG_ENB; 193 } 194 195 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 196 ti->goal.period = spi->sync_period; 197 198 if (ti->goal.period > aic->min_period) { 199 ti->goal.period = 0; 200 ti->goal.offset = 0; 201 } else if (ti->goal.period < aic->max_period) 202 ti->goal.period = aic->max_period; 203 } 204 205 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { 206 ti->goal.offset = spi->sync_offset; 207 if (ti->goal.offset == 0) 208 ti->goal.period = 0; 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 186 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 187 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 188 ti->flags |= TINFO_TAG_ENB; 189 else 190 ti->flags &= ~TINFO_TAG_ENB; 191 } 192 193 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 194 ti->goal.period = spi->sync_period; 195 196 if (ti->goal.period > aic->min_period) { 197 ti->goal.period = 0; 198 ti->goal.offset = 0; 199 } else if (ti->goal.period < aic->max_period) 200 ti->goal.period = aic->max_period; 201 } 202 203 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { 204 ti->goal.offset = spi->sync_offset; 205 if (ti->goal.offset == 0) 206 ti->goal.period = 0; 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]; 226 struct ccb_trans_settings_scsi *scsi = 227 &cts->proto_specific.scsi; 228 struct ccb_trans_settings_spi *spi = 229 &cts->xport_specific.spi; 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]; 223 struct ccb_trans_settings_scsi *scsi = 224 &cts->proto_specific.scsi; 225 struct ccb_trans_settings_spi *spi = 226 &cts->xport_specific.spi; 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 260 ccb->ccb_h.status = CAM_REQ_CMP; 261 xpt_done(ccb); 262 break; 263 } 264 case XPT_CALC_GEOMETRY: 265 { 266 cam_calc_geometry(&ccb->ccg, /*extended*/1); 267 xpt_done(ccb); 268 break; 269 } 270 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 271 aic_reset(aic, /*initiate_reset*/TRUE); 272 ccb->ccb_h.status = CAM_REQ_CMP; 273 xpt_done(ccb); 274 break; 275 case XPT_PATH_INQ: /* Path routing inquiry */ 276 { 277 struct ccb_pathinq *cpi = &ccb->cpi; 278 279 cpi->version_num = 1; /* XXX??? */ 280 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 281 cpi->target_sprt = 0; 282 cpi->hba_misc = 0; 283 cpi->hba_eng_cnt = 0; 284 cpi->max_target = 7; 285 cpi->max_lun = 7; 286 cpi->initiator_id = aic->initiator; 287 cpi->bus_id = cam_sim_bus(sim); 288 cpi->base_transfer_speed = 3300; 289 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 290 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 291 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 292 cpi->unit_number = cam_sim_unit(sim); 293 cpi->transport = XPORT_SPI; 294 cpi->transport_version = 2; 295 cpi->protocol = PROTO_SCSI; 296 cpi->protocol_version = SCSI_REV_2; 297 cpi->ccb_h.status = CAM_REQ_CMP; 298 xpt_done(ccb); 299 break; 300 } 301 default: 302 ccb->ccb_h.status = CAM_REQ_INVALID; 303 xpt_done(ccb); 304 break; 305 } 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 255 ccb->ccb_h.status = CAM_REQ_CMP; 256 xpt_done(ccb); 257 break; 258 } 259 case XPT_CALC_GEOMETRY: 260 { 261 cam_calc_geometry(&ccb->ccg, /*extended*/1); 262 xpt_done(ccb); 263 break; 264 } 265 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 266 aic_reset(aic, /*initiate_reset*/TRUE); 267 ccb->ccb_h.status = CAM_REQ_CMP; 268 xpt_done(ccb); 269 break; 270 case XPT_PATH_INQ: /* Path routing inquiry */ 271 { 272 struct ccb_pathinq *cpi = &ccb->cpi; 273 274 cpi->version_num = 1; /* XXX??? */ 275 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 276 cpi->target_sprt = 0; 277 cpi->hba_misc = 0; 278 cpi->hba_eng_cnt = 0; 279 cpi->max_target = 7; 280 cpi->max_lun = 7; 281 cpi->initiator_id = aic->initiator; 282 cpi->bus_id = cam_sim_bus(sim); 283 cpi->base_transfer_speed = 3300; 284 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 285 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 286 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 287 cpi->unit_number = cam_sim_unit(sim); 288 cpi->transport = XPORT_SPI; 289 cpi->transport_version = 2; 290 cpi->protocol = PROTO_SCSI; 291 cpi->protocol_version = SCSI_REV_2; 292 cpi->ccb_h.status = CAM_REQ_CMP; 293 xpt_done(ccb); 294 break; 295 } 296 default: 297 ccb->ccb_h.status = CAM_REQ_INVALID; 298 xpt_done(ccb); 299 break; 300 } 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{ 342 struct ccb_hdr *ccb_h; 343 struct aic_tinfo *ti; 344 345 if (aic->state != AIC_IDLE) 346 return; 347 348 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { 349 ti = &aic->tinfo[ccb_h->target_id]; 350 if ((ti->lubusy & (1 << ccb_h->target_lun)) == 0) { 351 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe); 352 aic->nexus = (struct aic_scb *)ccb_h->ccb_scb_ptr; 353 aic_select(aic); 354 return; 355 } 356 } 357 358 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_start: idle\n")); 359 360 aic_outb(aic, SIMODE0, ENSELDI); 361 aic_outb(aic, SIMODE1, ENSCSIRST); 362 aic_outb(aic, SCSISEQ, ENRESELI); 363} 364 365/* 366 * Start a selection. 367 */ 368static void 369aic_select(struct aic_softc *aic) 370{ 371 struct aic_scb *scb = aic->nexus; 372 373 CAM_DEBUG(scb->ccb->ccb_h.path, CAM_DEBUG_TRACE, 374 ("aic_select - ccb %p\n", scb->ccb)); 375 376 aic->state = AIC_SELECTING; 377 378 aic_outb(aic, DMACNTRL1, 0); 379 aic_outb(aic, SCSIID, aic->initiator << OID_S | scb->target); 380 aic_outb(aic, SXFRCTL1, STIMO_256ms | ENSTIMER | 381 (aic->flags & AIC_PARITY_ENABLE ? ENSPCHK : 0)); 382 383 aic_outb(aic, SIMODE0, ENSELDI|ENSELDO); 384 aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO); 385 aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO); 386} 387 388/* 389 * We have successfully selected a target, prepare for the information 390 * transfer phases. 391 */ 392static void 393aic_selected(struct aic_softc *aic) 394{ 395 struct aic_scb *scb = aic->nexus; 396 union ccb *ccb = scb->ccb; 397 struct aic_tinfo *ti = &aic->tinfo[scb->target]; 398 399 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 400 ("aic_selected - ccb %p\n", ccb)); 401 402 aic->state = AIC_HASNEXUS; 403 404 if (scb->flags & SCB_DEVICE_RESET) { 405 aic->msg_buf[0] = MSG_BUS_DEV_RESET; 406 aic->msg_len = 1; 407 aic->msg_outq = AIC_MSG_MSGBUF; 408 } else { 409 aic->msg_outq = AIC_MSG_IDENTIFY; 410 if ((ti->flags & TINFO_TAG_ENB) != 0 && 411 (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) 412 aic->msg_outq |= AIC_MSG_TAG_Q; 413 else 414 ti->lubusy |= 1 << scb->lun; 415 if ((ti->flags & TINFO_SDTR_NEGO) != 0) 416 aic->msg_outq |= AIC_MSG_SDTR; 417 } 418 419 aic_outb(aic, CLRSINT0, CLRSELDO); 420 aic_outb(aic, CLRSINT1, CLRBUSFREE); 421 aic_outb(aic, SCSISEQ, ENAUTOATNP); 422 aic_outb(aic, SIMODE0, 0); 423 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 424 aic_outb(aic, SCSIRATE, ti->scsirate); 425} 426 427/* 428 * We are re-selected by a target, save the target id and wait for the 429 * target to further identify itself. 430 */ 431static void 432aic_reselected(struct aic_softc *aic) 433{ 434 u_int8_t selid; 435 436 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reselected\n")); 437 438 /* 439 * If we have started a selection, it must have lost out in 440 * the arbitration, put the command back to the pending queue. 441 */ 442 if (aic->nexus) { 443 TAILQ_INSERT_HEAD(&aic->pending_ccbs, 444 &aic->nexus->ccb->ccb_h, sim_links.tqe); 445 aic->nexus = NULL; 446 } 447 448 selid = aic_inb(aic, SELID) & ~(1 << aic->initiator); 449 if (selid & (selid - 1)) { 450 /* this should never have happened */ 451 printf("aic_reselected: invalid selid %x\n", selid); 452 aic_reset(aic, /*initiate_reset*/TRUE); 453 return; 454 } 455 456 aic->state = AIC_RESELECTED; 457 aic->target = ffs(selid) - 1; 458 aic->lun = -1; 459 460 aic_outb(aic, CLRSINT0, CLRSELDI); 461 aic_outb(aic, CLRSINT1, CLRBUSFREE); 462 aic_outb(aic, SIMODE0, 0); 463 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 464 aic_outb(aic, SCSISEQ, ENAUTOATNP); 465 aic_outb(aic, SCSIRATE, aic->tinfo[aic->target].scsirate); 466} 467 468/* 469 * Raise ATNO to signal the target that we have a message for it. 470 */ 471static __inline void 472aic_sched_msgout(struct aic_softc *aic, u_int8_t msg) 473{ 474 if (msg) { 475 aic->msg_buf[0] = msg; 476 aic->msg_len = 1; 477 } 478 aic->msg_outq |= AIC_MSG_MSGBUF; 479 aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO); 480} 481 482/* 483 * Wait for SPIORDY (SCSI PIO ready) flag, or a phase change. 484 */ 485static __inline int 486aic_spiordy(struct aic_softc *aic) 487{ 488 while (!(aic_inb(aic, DMASTAT) & INTSTAT) && 489 !(aic_inb(aic, SSTAT0) & SPIORDY)) 490 ; 491 return !(aic_inb(aic, DMASTAT) & INTSTAT); 492} 493 494/* 495 * Reestablish a disconnected nexus. 496 */ 497static void 498aic_reconnect(struct aic_softc *aic, int tag) 499{ 500 struct aic_scb *scb; 501 struct ccb_hdr *ccb_h; 502 503 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reconnect\n")); 504 505 /* Find the nexus */ 506 scb = NULL; 507 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { 508 scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 509 if (scb->target == aic->target && scb->lun == aic->lun && 510 (tag == -1 || scb->tag == tag)) 511 break; 512 } 513 514 /* ABORT if nothing is found */ 515 if (!ccb_h) { 516 if (tag == -1) 517 aic_sched_msgout(aic, MSG_ABORT); 518 else 519 aic_sched_msgout(aic, MSG_ABORT_TAG); 520 xpt_async(AC_UNSOL_RESEL, aic->path, NULL); 521 return; 522 } 523 524 /* Reestablish the nexus */ 525 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 526 aic->nexus = scb; 527 scb->flags &= ~SCB_DISCONNECTED; 528 aic->state = AIC_HASNEXUS; 529} 530 531/* 532 * Read messages. 533 */ 534static void 535aic_msgin(struct aic_softc *aic) 536{ 537 int msglen; 538 539 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgin\n")); 540 541 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 542 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 543 544 aic->flags &= ~AIC_DROP_MSGIN; 545 aic->msg_len = 0; 546 do { 547 /* 548 * If a parity error is detected, drop the remaining 549 * bytes and inform the target so it could resend 550 * the messages. 551 */ 552 if (aic_inb(aic, SSTAT1) & SCSIPERR) { 553 aic_outb(aic, CLRSINT1, CLRSCSIPERR); 554 aic->flags |= AIC_DROP_MSGIN; 555 aic_sched_msgout(aic, MSG_PARITY_ERROR); 556 } 557 if ((aic->flags & AIC_DROP_MSGIN)) { 558 aic_inb(aic, SCSIDAT); 559 continue; 560 } 561 /* read the message byte without ACKing on it */ 562 aic->msg_buf[aic->msg_len++] = aic_inb(aic, SCSIBUS); 563 if (aic->msg_buf[0] == MSG_EXTENDED) { 564 if (aic->msg_len < 2) { 565 (void) aic_inb(aic, SCSIDAT); 566 continue; 567 } 568 switch (aic->msg_buf[2]) { 569 case MSG_EXT_SDTR: 570 msglen = MSG_EXT_SDTR_LEN; 571 break; 572 case MSG_EXT_WDTR: 573 msglen = MSG_EXT_WDTR_LEN; 574 break; 575 default: 576 msglen = 0; 577 break; 578 } 579 if (aic->msg_buf[1] != msglen) { 580 aic->flags |= AIC_DROP_MSGIN; 581 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 582 } 583 msglen += 2; 584 } else if (aic->msg_buf[0] >= 0x20 && aic->msg_buf[0] <= 0x2f) 585 msglen = 2; 586 else 587 msglen = 1; 588 /* 589 * If we have a complete message, handle it before the final 590 * ACK (in case we decide to reject the message). 591 */ 592 if (aic->msg_len == msglen) { 593 aic_handle_msgin(aic); 594 aic->msg_len = 0; 595 } 596 /* ACK on the message byte */ 597 (void) aic_inb(aic, SCSIDAT); 598 } while (aic_spiordy(aic)); 599 600 aic_outb(aic, SXFRCTL0, CHEN); 601 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 602} 603 604/* 605 * Handle a message. 606 */ 607static void 608aic_handle_msgin(struct aic_softc *aic) 609{ 610 struct aic_scb *scb; 611 struct ccb_hdr *ccb_h; 612 struct aic_tinfo *ti; 613 struct ccb_trans_settings neg; 614 struct ccb_trans_settings_spi *spi = &neg.xport_specific.spi; 615 616 if (aic->state == AIC_RESELECTED) { 617 if (!MSG_ISIDENTIFY(aic->msg_buf[0])) { 618 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 619 return; 620 } 621 aic->lun = aic->msg_buf[0] & MSG_IDENTIFY_LUNMASK; 622 if (aic->tinfo[aic->target].lubusy & (1 << aic->lun)) 623 aic_reconnect(aic, -1); 624 else 625 aic->state = AIC_RECONNECTING; 626 return; 627 } 628 629 if (aic->state == AIC_RECONNECTING) { 630 if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) { 631 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 632 return; 633 } 634 aic_reconnect(aic, aic->msg_buf[1]); 635 return; 636 } 637 638 switch (aic->msg_buf[0]) { 639 case MSG_CMDCOMPLETE: { 640 struct ccb_scsiio *csio; 641 scb = aic->nexus; 642 ccb_h = &scb->ccb->ccb_h; 643 csio = &scb->ccb->csio; 644 if ((scb->flags & SCB_SENSE) != 0) { 645 /* auto REQUEST SENSE command */ 646 scb->flags &= ~SCB_SENSE; 647 csio->sense_resid = scb->data_len; 648 if (scb->status == SCSI_STATUS_OK) { 649 ccb_h->status |= 650 CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID; 651 /*scsi_sense_print(csio);*/ 652 } else { 653 ccb_h->status |= CAM_AUTOSENSE_FAIL; 654 printf("ccb %p sense failed %x\n", 655 ccb_h, scb->status); 656 } 657 } else { 658 csio->scsi_status = scb->status; 659 csio->resid = scb->data_len; 660 if (scb->status == SCSI_STATUS_OK) { 661 /* everything goes well */ 662 ccb_h->status |= CAM_REQ_CMP; 663 } else if ((ccb_h->flags & CAM_DIS_AUTOSENSE) == 0 && 664 (csio->scsi_status == SCSI_STATUS_CHECK_COND || 665 csio->scsi_status == SCSI_STATUS_CMD_TERMINATED)) { 666 /* try to retrieve sense information */ 667 scb->flags |= SCB_SENSE; 668 aic->flags |= AIC_BUSFREE_OK; 669 return; 670 } else 671 ccb_h->status |= CAM_SCSI_STATUS_ERROR; 672 } 673 aic_done(aic, scb); 674 aic->flags |= AIC_BUSFREE_OK; 675 break; 676 } 677 case MSG_EXTENDED: 678 switch (aic->msg_buf[2]) { 679 case MSG_EXT_SDTR: 680 scb = aic->nexus; 681 ti = &aic->tinfo[scb->target]; 682 if (ti->flags & TINFO_SDTR_SENT) { 683 ti->current.period = aic->msg_buf[3]; 684 ti->current.offset = aic->msg_buf[4]; 685 } else { 686 ti->current.period = aic->msg_buf[3] = 687 max(ti->goal.period, aic->msg_buf[3]); 688 ti->current.offset = aic->msg_buf[4] = 689 min(ti->goal.offset, aic->msg_buf[4]); 690 /* 691 * The target initiated the negotiation, 692 * send back a response. 693 */ 694 aic_sched_msgout(aic, 0); 695 } 696 ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); 697 ti->scsirate = ti->current.offset ? ti->current.offset | 698 ((ti->current.period * 4 + 49) / 50 - 2) << 4 : 0; 699 aic_outb(aic, SCSIRATE, ti->scsirate); 700 memset(&neg, 0, sizeof (neg)); 701 neg.protocol = PROTO_SCSI; 702 neg.protocol_version = SCSI_REV_2; 703 neg.transport = XPORT_SPI; 704 neg.transport_version = 2; 705 spi->sync_period = ti->goal.period = ti->current.period; 706 spi->sync_offset = ti->goal.offset = ti->current.offset; 707 spi->valid = CTS_SPI_VALID_SYNC_RATE 708 | CTS_SPI_VALID_SYNC_OFFSET; 709 ccb_h = &scb->ccb->ccb_h; 710 xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); 711 xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); 712 break; 713 case MSG_EXT_WDTR: 714 default: 715 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 716 break; 717 } 718 break; 719 case MSG_DISCONNECT: 720 scb = aic->nexus; 721 ccb_h = &scb->ccb->ccb_h; 722 TAILQ_INSERT_TAIL(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 723 scb->flags |= SCB_DISCONNECTED; 724 aic->flags |= AIC_BUSFREE_OK; 725 aic->nexus = NULL; 726 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE, ("disconnected\n")); 727 break; 728 case MSG_MESSAGE_REJECT: 729 switch (aic->msg_outq & -aic->msg_outq) { 730 case AIC_MSG_TAG_Q: 731 scb = aic->nexus; 732 ti = &aic->tinfo[scb->target]; 733 ti->flags &= ~TINFO_TAG_ENB; 734 ti->lubusy |= 1 << scb->lun; 735 break; 736 case AIC_MSG_SDTR: 737 scb = aic->nexus; 738 ti = &aic->tinfo[scb->target]; 739 ti->current.period = ti->goal.period = 0; 740 ti->current.offset = ti->goal.offset = 0; 741 ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); 742 ti->scsirate = 0; 743 aic_outb(aic, SCSIRATE, ti->scsirate); 744 memset(&neg, 0, sizeof (neg)); 745 neg.protocol = PROTO_SCSI; 746 neg.protocol_version = SCSI_REV_2; 747 neg.transport = XPORT_SPI; 748 neg.transport_version = 2; 749 spi->sync_period = ti->current.period; 750 spi->sync_offset = ti->current.offset; 751 spi->valid = CTS_SPI_VALID_SYNC_RATE 752 | CTS_SPI_VALID_SYNC_OFFSET; 753 ccb_h = &scb->ccb->ccb_h; 754 xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); 755 xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); 756 break; 757 default: 758 break; 759 } 760 break; 761 case MSG_SAVEDATAPOINTER: 762 break; 763 case MSG_RESTOREPOINTERS: 764 break; 765 case MSG_NOOP: 766 break; 767 default: 768 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 769 break; 770 } 771} 772 773/* 774 * Send messages. 775 */ 776static void 777aic_msgout(struct aic_softc *aic) 778{ 779 struct aic_scb *scb; 780 union ccb *ccb; 781 struct aic_tinfo *ti; 782 int msgidx = 0; 783 784 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgout\n")); 785 786 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 787 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 788 789 /* 790 * If the previous phase is also the message out phase, 791 * we need to retransmit all the messages, probably 792 * because the target has detected a parity error during 793 * the past transmission. 794 */ 795 if (aic->prev_phase == PH_MSGOUT) 796 aic->msg_outq = aic->msg_sent; 797 798 do { 799 int q = aic->msg_outq; 800 if (msgidx > 0 && msgidx == aic->msg_len) { 801 /* complete message sent, start the next one */ 802 q &= -q; 803 aic->msg_sent |= q; 804 aic->msg_outq ^= q; 805 q = aic->msg_outq; 806 msgidx = 0; 807 } 808 if (msgidx == 0) { 809 /* setup the message */ 810 switch (q & -q) { 811 case AIC_MSG_IDENTIFY: 812 scb = aic->nexus; 813 ccb = scb->ccb; 814 ti = &aic->tinfo[scb->target]; 815 aic->msg_buf[0] = MSG_IDENTIFY(scb->lun, 816 (ti->flags & TINFO_DISC_ENB) && 817 !(ccb->ccb_h.flags & CAM_DIS_DISCONNECT)); 818 aic->msg_len = 1; 819 break; 820 case AIC_MSG_TAG_Q: 821 scb = aic->nexus; 822 ccb = scb->ccb; 823 aic->msg_buf[0] = ccb->csio.tag_action; 824 aic->msg_buf[1] = scb->tag; 825 aic->msg_len = 2; 826 break; 827 case AIC_MSG_SDTR: 828 scb = aic->nexus; 829 ti = &aic->tinfo[scb->target]; 830 aic->msg_buf[0] = MSG_EXTENDED; 831 aic->msg_buf[1] = MSG_EXT_SDTR_LEN; 832 aic->msg_buf[2] = MSG_EXT_SDTR; 833 aic->msg_buf[3] = ti->goal.period; 834 aic->msg_buf[4] = ti->goal.offset; 835 aic->msg_len = MSG_EXT_SDTR_LEN + 2; 836 ti->flags |= TINFO_SDTR_SENT; 837 break; 838 case AIC_MSG_MSGBUF: 839 /* a single message already in the buffer */ 840 if (aic->msg_buf[0] == MSG_BUS_DEV_RESET || 841 aic->msg_buf[0] == MSG_ABORT || 842 aic->msg_buf[0] == MSG_ABORT_TAG) 843 aic->flags |= AIC_BUSFREE_OK; 844 break; 845 } 846 } 847 /* 848 * If this is the last message byte of all messages, 849 * clear ATNO to signal transmission complete. 850 */ 851 if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1) 852 aic_outb(aic, CLRSINT1, CLRATNO); 853 /* transmit the message byte */ 854 aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]); 855 } while (aic_spiordy(aic)); 856 857 aic_outb(aic, SXFRCTL0, CHEN); 858 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 859} 860 861/* 862 * Read data bytes. 863 */ 864static void 865aic_datain(struct aic_softc *aic) 866{ 867 struct aic_scb *scb = aic->nexus; 868 u_int8_t dmastat, dmacntrl0; 869 int n; 870 871 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_datain\n")); 872 873 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 874 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 875 876 dmacntrl0 = ENDMA; 877 if (aic->flags & AIC_DWIO_ENABLE) 878 dmacntrl0 |= DWORDPIO; 879 aic_outb(aic, DMACNTRL0, dmacntrl0); 880 881 while (scb->data_len > 0) { 882 for (;;) { 883 /* wait for the fifo to fill up or a phase change */ 884 dmastat = aic_inb(aic, DMASTAT); 885 if (dmastat & (INTSTAT|DFIFOFULL)) 886 break; 887 } 888 if (dmastat & DFIFOFULL) { 889 n = FIFOSIZE; 890 } else { 891 /* 892 * No more data, wait for the remaining bytes in 893 * the scsi fifo to be transfer to the host fifo. 894 */ 895 while (!(aic_inb(aic, SSTAT2) & SEMPTY)) 896 ; 897 n = aic_inb(aic, FIFOSTAT); 898 } 899 n = imin(scb->data_len, n); 900 if (aic->flags & AIC_DWIO_ENABLE) { 901 if (n >= 12) { 902 aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2); 903 scb->data_ptr += n & ~3; 904 scb->data_len -= n & ~3; 905 n &= 3; 906 } 907 } else { 908 if (n >= 8) { 909 aic_insw(aic, DMADATA, scb->data_ptr, n >> 1); 910 scb->data_ptr += n & ~1; 911 scb->data_len -= n & ~1; 912 n &= 1; 913 } 914 } 915 if (n) { 916 aic_outb(aic, DMACNTRL0, ENDMA|B8MODE); 917 aic_insb(aic, DMADATA, scb->data_ptr, n); 918 scb->data_ptr += n; 919 scb->data_len -= n; 920 aic_outb(aic, DMACNTRL0, dmacntrl0); 921 } 922 923 if (dmastat & INTSTAT) 924 break; 925 } 926 927 aic_outb(aic, SXFRCTL0, CHEN); 928 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 929} 930 931/* 932 * Send data bytes. 933 */ 934static void 935aic_dataout(struct aic_softc *aic) 936{ 937 struct aic_scb *scb = aic->nexus; 938 u_int8_t dmastat, dmacntrl0, sstat2; 939 int n; 940 941 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_dataout\n")); 942 943 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 944 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 945 946 dmacntrl0 = ENDMA|WRITE; 947 if (aic->flags & AIC_DWIO_ENABLE) 948 dmacntrl0 |= DWORDPIO; 949 aic_outb(aic, DMACNTRL0, dmacntrl0); 950 951 while (scb->data_len > 0) { 952 for (;;) { 953 /* wait for the fifo to clear up or a phase change */ 954 dmastat = aic_inb(aic, DMASTAT); 955 if (dmastat & (INTSTAT|DFIFOEMP)) 956 break; 957 } 958 if (dmastat & INTSTAT) 959 break; 960 n = imin(scb->data_len, FIFOSIZE); 961 if (aic->flags & AIC_DWIO_ENABLE) { 962 if (n >= 12) { 963 aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2); 964 scb->data_ptr += n & ~3; 965 scb->data_len -= n & ~3; 966 n &= 3; 967 } 968 } else { 969 if (n >= 8) { 970 aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1); 971 scb->data_ptr += n & ~1; 972 scb->data_len -= n & ~1; 973 n &= 1; 974 } 975 } 976 if (n) { 977 aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE); 978 aic_outsb(aic, DMADATA, scb->data_ptr, n); 979 scb->data_ptr += n; 980 scb->data_len -= n; 981 aic_outb(aic, DMACNTRL0, dmacntrl0); 982 } 983 } 984 985 for (;;) { 986 /* wait until all bytes in the fifos are transmitted */ 987 dmastat = aic_inb(aic, DMASTAT); 988 sstat2 = aic_inb(aic, SSTAT2); 989 if ((dmastat & DFIFOEMP) && (sstat2 & SEMPTY)) 990 break; 991 if (dmastat & INTSTAT) { 992 /* adjust for untransmitted bytes */ 993 n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf); 994 scb->data_ptr -= n; 995 scb->data_len += n; 996 /* clear the fifo */ 997 aic_outb(aic, SXFRCTL0, CHEN|CLRCH); 998 aic_outb(aic, DMACNTRL0, RSTFIFO); 999 break; 1000 } 1001 } 1002 1003 aic_outb(aic, SXFRCTL0, CHEN); 1004 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 1005} 1006 1007/* 1008 * Send the scsi command. 1009 */ 1010static void 1011aic_cmd(struct aic_softc *aic) 1012{ 1013 struct aic_scb *scb = aic->nexus; 1014 struct scsi_request_sense sense_cmd; 1015 1016 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_cmd\n")); 1017 1018 if (scb->flags & SCB_SENSE) { 1019 /* autosense request */ 1020 sense_cmd.opcode = REQUEST_SENSE; 1021 sense_cmd.byte2 = scb->lun << 5; 1022 sense_cmd.length = scb->ccb->csio.sense_len; 1023 sense_cmd.control = 0; 1024 sense_cmd.unused[0] = 0; 1025 sense_cmd.unused[1] = 0; 1026 scb->cmd_ptr = (u_int8_t *)&sense_cmd; 1027 scb->cmd_len = sizeof(sense_cmd); 1028 scb->data_ptr = (u_int8_t *)&scb->ccb->csio.sense_data; 1029 scb->data_len = scb->ccb->csio.sense_len; 1030 } 1031 1032 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 1033 aic_outb(aic, DMACNTRL0, ENDMA|WRITE); 1034 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 1035 aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, scb->cmd_len >> 1); 1036 while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 && 1037 (aic_inb(aic, DMASTAT) & INTSTAT) == 0) 1038 ; 1039 aic_outb(aic, SXFRCTL0, CHEN); 1040 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 1041} 1042 1043/* 1044 * Finish off a command. The caller is responsible to remove the ccb 1045 * from any queue. 1046 */ 1047static void 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{ 334 struct ccb_hdr *ccb_h; 335 struct aic_tinfo *ti; 336 337 if (aic->state != AIC_IDLE) 338 return; 339 340 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { 341 ti = &aic->tinfo[ccb_h->target_id]; 342 if ((ti->lubusy & (1 << ccb_h->target_lun)) == 0) { 343 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe); 344 aic->nexus = (struct aic_scb *)ccb_h->ccb_scb_ptr; 345 aic_select(aic); 346 return; 347 } 348 } 349 350 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_start: idle\n")); 351 352 aic_outb(aic, SIMODE0, ENSELDI); 353 aic_outb(aic, SIMODE1, ENSCSIRST); 354 aic_outb(aic, SCSISEQ, ENRESELI); 355} 356 357/* 358 * Start a selection. 359 */ 360static void 361aic_select(struct aic_softc *aic) 362{ 363 struct aic_scb *scb = aic->nexus; 364 365 CAM_DEBUG(scb->ccb->ccb_h.path, CAM_DEBUG_TRACE, 366 ("aic_select - ccb %p\n", scb->ccb)); 367 368 aic->state = AIC_SELECTING; 369 370 aic_outb(aic, DMACNTRL1, 0); 371 aic_outb(aic, SCSIID, aic->initiator << OID_S | scb->target); 372 aic_outb(aic, SXFRCTL1, STIMO_256ms | ENSTIMER | 373 (aic->flags & AIC_PARITY_ENABLE ? ENSPCHK : 0)); 374 375 aic_outb(aic, SIMODE0, ENSELDI|ENSELDO); 376 aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO); 377 aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO); 378} 379 380/* 381 * We have successfully selected a target, prepare for the information 382 * transfer phases. 383 */ 384static void 385aic_selected(struct aic_softc *aic) 386{ 387 struct aic_scb *scb = aic->nexus; 388 union ccb *ccb = scb->ccb; 389 struct aic_tinfo *ti = &aic->tinfo[scb->target]; 390 391 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 392 ("aic_selected - ccb %p\n", ccb)); 393 394 aic->state = AIC_HASNEXUS; 395 396 if (scb->flags & SCB_DEVICE_RESET) { 397 aic->msg_buf[0] = MSG_BUS_DEV_RESET; 398 aic->msg_len = 1; 399 aic->msg_outq = AIC_MSG_MSGBUF; 400 } else { 401 aic->msg_outq = AIC_MSG_IDENTIFY; 402 if ((ti->flags & TINFO_TAG_ENB) != 0 && 403 (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) 404 aic->msg_outq |= AIC_MSG_TAG_Q; 405 else 406 ti->lubusy |= 1 << scb->lun; 407 if ((ti->flags & TINFO_SDTR_NEGO) != 0) 408 aic->msg_outq |= AIC_MSG_SDTR; 409 } 410 411 aic_outb(aic, CLRSINT0, CLRSELDO); 412 aic_outb(aic, CLRSINT1, CLRBUSFREE); 413 aic_outb(aic, SCSISEQ, ENAUTOATNP); 414 aic_outb(aic, SIMODE0, 0); 415 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 416 aic_outb(aic, SCSIRATE, ti->scsirate); 417} 418 419/* 420 * We are re-selected by a target, save the target id and wait for the 421 * target to further identify itself. 422 */ 423static void 424aic_reselected(struct aic_softc *aic) 425{ 426 u_int8_t selid; 427 428 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reselected\n")); 429 430 /* 431 * If we have started a selection, it must have lost out in 432 * the arbitration, put the command back to the pending queue. 433 */ 434 if (aic->nexus) { 435 TAILQ_INSERT_HEAD(&aic->pending_ccbs, 436 &aic->nexus->ccb->ccb_h, sim_links.tqe); 437 aic->nexus = NULL; 438 } 439 440 selid = aic_inb(aic, SELID) & ~(1 << aic->initiator); 441 if (selid & (selid - 1)) { 442 /* this should never have happened */ 443 printf("aic_reselected: invalid selid %x\n", selid); 444 aic_reset(aic, /*initiate_reset*/TRUE); 445 return; 446 } 447 448 aic->state = AIC_RESELECTED; 449 aic->target = ffs(selid) - 1; 450 aic->lun = -1; 451 452 aic_outb(aic, CLRSINT0, CLRSELDI); 453 aic_outb(aic, CLRSINT1, CLRBUSFREE); 454 aic_outb(aic, SIMODE0, 0); 455 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 456 aic_outb(aic, SCSISEQ, ENAUTOATNP); 457 aic_outb(aic, SCSIRATE, aic->tinfo[aic->target].scsirate); 458} 459 460/* 461 * Raise ATNO to signal the target that we have a message for it. 462 */ 463static __inline void 464aic_sched_msgout(struct aic_softc *aic, u_int8_t msg) 465{ 466 if (msg) { 467 aic->msg_buf[0] = msg; 468 aic->msg_len = 1; 469 } 470 aic->msg_outq |= AIC_MSG_MSGBUF; 471 aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO); 472} 473 474/* 475 * Wait for SPIORDY (SCSI PIO ready) flag, or a phase change. 476 */ 477static __inline int 478aic_spiordy(struct aic_softc *aic) 479{ 480 while (!(aic_inb(aic, DMASTAT) & INTSTAT) && 481 !(aic_inb(aic, SSTAT0) & SPIORDY)) 482 ; 483 return !(aic_inb(aic, DMASTAT) & INTSTAT); 484} 485 486/* 487 * Reestablish a disconnected nexus. 488 */ 489static void 490aic_reconnect(struct aic_softc *aic, int tag) 491{ 492 struct aic_scb *scb; 493 struct ccb_hdr *ccb_h; 494 495 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reconnect\n")); 496 497 /* Find the nexus */ 498 scb = NULL; 499 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { 500 scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 501 if (scb->target == aic->target && scb->lun == aic->lun && 502 (tag == -1 || scb->tag == tag)) 503 break; 504 } 505 506 /* ABORT if nothing is found */ 507 if (!ccb_h) { 508 if (tag == -1) 509 aic_sched_msgout(aic, MSG_ABORT); 510 else 511 aic_sched_msgout(aic, MSG_ABORT_TAG); 512 xpt_async(AC_UNSOL_RESEL, aic->path, NULL); 513 return; 514 } 515 516 /* Reestablish the nexus */ 517 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 518 aic->nexus = scb; 519 scb->flags &= ~SCB_DISCONNECTED; 520 aic->state = AIC_HASNEXUS; 521} 522 523/* 524 * Read messages. 525 */ 526static void 527aic_msgin(struct aic_softc *aic) 528{ 529 int msglen; 530 531 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgin\n")); 532 533 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 534 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 535 536 aic->flags &= ~AIC_DROP_MSGIN; 537 aic->msg_len = 0; 538 do { 539 /* 540 * If a parity error is detected, drop the remaining 541 * bytes and inform the target so it could resend 542 * the messages. 543 */ 544 if (aic_inb(aic, SSTAT1) & SCSIPERR) { 545 aic_outb(aic, CLRSINT1, CLRSCSIPERR); 546 aic->flags |= AIC_DROP_MSGIN; 547 aic_sched_msgout(aic, MSG_PARITY_ERROR); 548 } 549 if ((aic->flags & AIC_DROP_MSGIN)) { 550 aic_inb(aic, SCSIDAT); 551 continue; 552 } 553 /* read the message byte without ACKing on it */ 554 aic->msg_buf[aic->msg_len++] = aic_inb(aic, SCSIBUS); 555 if (aic->msg_buf[0] == MSG_EXTENDED) { 556 if (aic->msg_len < 2) { 557 (void) aic_inb(aic, SCSIDAT); 558 continue; 559 } 560 switch (aic->msg_buf[2]) { 561 case MSG_EXT_SDTR: 562 msglen = MSG_EXT_SDTR_LEN; 563 break; 564 case MSG_EXT_WDTR: 565 msglen = MSG_EXT_WDTR_LEN; 566 break; 567 default: 568 msglen = 0; 569 break; 570 } 571 if (aic->msg_buf[1] != msglen) { 572 aic->flags |= AIC_DROP_MSGIN; 573 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 574 } 575 msglen += 2; 576 } else if (aic->msg_buf[0] >= 0x20 && aic->msg_buf[0] <= 0x2f) 577 msglen = 2; 578 else 579 msglen = 1; 580 /* 581 * If we have a complete message, handle it before the final 582 * ACK (in case we decide to reject the message). 583 */ 584 if (aic->msg_len == msglen) { 585 aic_handle_msgin(aic); 586 aic->msg_len = 0; 587 } 588 /* ACK on the message byte */ 589 (void) aic_inb(aic, SCSIDAT); 590 } while (aic_spiordy(aic)); 591 592 aic_outb(aic, SXFRCTL0, CHEN); 593 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 594} 595 596/* 597 * Handle a message. 598 */ 599static void 600aic_handle_msgin(struct aic_softc *aic) 601{ 602 struct aic_scb *scb; 603 struct ccb_hdr *ccb_h; 604 struct aic_tinfo *ti; 605 struct ccb_trans_settings neg; 606 struct ccb_trans_settings_spi *spi = &neg.xport_specific.spi; 607 608 if (aic->state == AIC_RESELECTED) { 609 if (!MSG_ISIDENTIFY(aic->msg_buf[0])) { 610 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 611 return; 612 } 613 aic->lun = aic->msg_buf[0] & MSG_IDENTIFY_LUNMASK; 614 if (aic->tinfo[aic->target].lubusy & (1 << aic->lun)) 615 aic_reconnect(aic, -1); 616 else 617 aic->state = AIC_RECONNECTING; 618 return; 619 } 620 621 if (aic->state == AIC_RECONNECTING) { 622 if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) { 623 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 624 return; 625 } 626 aic_reconnect(aic, aic->msg_buf[1]); 627 return; 628 } 629 630 switch (aic->msg_buf[0]) { 631 case MSG_CMDCOMPLETE: { 632 struct ccb_scsiio *csio; 633 scb = aic->nexus; 634 ccb_h = &scb->ccb->ccb_h; 635 csio = &scb->ccb->csio; 636 if ((scb->flags & SCB_SENSE) != 0) { 637 /* auto REQUEST SENSE command */ 638 scb->flags &= ~SCB_SENSE; 639 csio->sense_resid = scb->data_len; 640 if (scb->status == SCSI_STATUS_OK) { 641 ccb_h->status |= 642 CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID; 643 /*scsi_sense_print(csio);*/ 644 } else { 645 ccb_h->status |= CAM_AUTOSENSE_FAIL; 646 printf("ccb %p sense failed %x\n", 647 ccb_h, scb->status); 648 } 649 } else { 650 csio->scsi_status = scb->status; 651 csio->resid = scb->data_len; 652 if (scb->status == SCSI_STATUS_OK) { 653 /* everything goes well */ 654 ccb_h->status |= CAM_REQ_CMP; 655 } else if ((ccb_h->flags & CAM_DIS_AUTOSENSE) == 0 && 656 (csio->scsi_status == SCSI_STATUS_CHECK_COND || 657 csio->scsi_status == SCSI_STATUS_CMD_TERMINATED)) { 658 /* try to retrieve sense information */ 659 scb->flags |= SCB_SENSE; 660 aic->flags |= AIC_BUSFREE_OK; 661 return; 662 } else 663 ccb_h->status |= CAM_SCSI_STATUS_ERROR; 664 } 665 aic_done(aic, scb); 666 aic->flags |= AIC_BUSFREE_OK; 667 break; 668 } 669 case MSG_EXTENDED: 670 switch (aic->msg_buf[2]) { 671 case MSG_EXT_SDTR: 672 scb = aic->nexus; 673 ti = &aic->tinfo[scb->target]; 674 if (ti->flags & TINFO_SDTR_SENT) { 675 ti->current.period = aic->msg_buf[3]; 676 ti->current.offset = aic->msg_buf[4]; 677 } else { 678 ti->current.period = aic->msg_buf[3] = 679 max(ti->goal.period, aic->msg_buf[3]); 680 ti->current.offset = aic->msg_buf[4] = 681 min(ti->goal.offset, aic->msg_buf[4]); 682 /* 683 * The target initiated the negotiation, 684 * send back a response. 685 */ 686 aic_sched_msgout(aic, 0); 687 } 688 ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); 689 ti->scsirate = ti->current.offset ? ti->current.offset | 690 ((ti->current.period * 4 + 49) / 50 - 2) << 4 : 0; 691 aic_outb(aic, SCSIRATE, ti->scsirate); 692 memset(&neg, 0, sizeof (neg)); 693 neg.protocol = PROTO_SCSI; 694 neg.protocol_version = SCSI_REV_2; 695 neg.transport = XPORT_SPI; 696 neg.transport_version = 2; 697 spi->sync_period = ti->goal.period = ti->current.period; 698 spi->sync_offset = ti->goal.offset = ti->current.offset; 699 spi->valid = CTS_SPI_VALID_SYNC_RATE 700 | CTS_SPI_VALID_SYNC_OFFSET; 701 ccb_h = &scb->ccb->ccb_h; 702 xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); 703 xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); 704 break; 705 case MSG_EXT_WDTR: 706 default: 707 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 708 break; 709 } 710 break; 711 case MSG_DISCONNECT: 712 scb = aic->nexus; 713 ccb_h = &scb->ccb->ccb_h; 714 TAILQ_INSERT_TAIL(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 715 scb->flags |= SCB_DISCONNECTED; 716 aic->flags |= AIC_BUSFREE_OK; 717 aic->nexus = NULL; 718 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE, ("disconnected\n")); 719 break; 720 case MSG_MESSAGE_REJECT: 721 switch (aic->msg_outq & -aic->msg_outq) { 722 case AIC_MSG_TAG_Q: 723 scb = aic->nexus; 724 ti = &aic->tinfo[scb->target]; 725 ti->flags &= ~TINFO_TAG_ENB; 726 ti->lubusy |= 1 << scb->lun; 727 break; 728 case AIC_MSG_SDTR: 729 scb = aic->nexus; 730 ti = &aic->tinfo[scb->target]; 731 ti->current.period = ti->goal.period = 0; 732 ti->current.offset = ti->goal.offset = 0; 733 ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); 734 ti->scsirate = 0; 735 aic_outb(aic, SCSIRATE, ti->scsirate); 736 memset(&neg, 0, sizeof (neg)); 737 neg.protocol = PROTO_SCSI; 738 neg.protocol_version = SCSI_REV_2; 739 neg.transport = XPORT_SPI; 740 neg.transport_version = 2; 741 spi->sync_period = ti->current.period; 742 spi->sync_offset = ti->current.offset; 743 spi->valid = CTS_SPI_VALID_SYNC_RATE 744 | CTS_SPI_VALID_SYNC_OFFSET; 745 ccb_h = &scb->ccb->ccb_h; 746 xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); 747 xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); 748 break; 749 default: 750 break; 751 } 752 break; 753 case MSG_SAVEDATAPOINTER: 754 break; 755 case MSG_RESTOREPOINTERS: 756 break; 757 case MSG_NOOP: 758 break; 759 default: 760 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 761 break; 762 } 763} 764 765/* 766 * Send messages. 767 */ 768static void 769aic_msgout(struct aic_softc *aic) 770{ 771 struct aic_scb *scb; 772 union ccb *ccb; 773 struct aic_tinfo *ti; 774 int msgidx = 0; 775 776 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgout\n")); 777 778 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 779 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 780 781 /* 782 * If the previous phase is also the message out phase, 783 * we need to retransmit all the messages, probably 784 * because the target has detected a parity error during 785 * the past transmission. 786 */ 787 if (aic->prev_phase == PH_MSGOUT) 788 aic->msg_outq = aic->msg_sent; 789 790 do { 791 int q = aic->msg_outq; 792 if (msgidx > 0 && msgidx == aic->msg_len) { 793 /* complete message sent, start the next one */ 794 q &= -q; 795 aic->msg_sent |= q; 796 aic->msg_outq ^= q; 797 q = aic->msg_outq; 798 msgidx = 0; 799 } 800 if (msgidx == 0) { 801 /* setup the message */ 802 switch (q & -q) { 803 case AIC_MSG_IDENTIFY: 804 scb = aic->nexus; 805 ccb = scb->ccb; 806 ti = &aic->tinfo[scb->target]; 807 aic->msg_buf[0] = MSG_IDENTIFY(scb->lun, 808 (ti->flags & TINFO_DISC_ENB) && 809 !(ccb->ccb_h.flags & CAM_DIS_DISCONNECT)); 810 aic->msg_len = 1; 811 break; 812 case AIC_MSG_TAG_Q: 813 scb = aic->nexus; 814 ccb = scb->ccb; 815 aic->msg_buf[0] = ccb->csio.tag_action; 816 aic->msg_buf[1] = scb->tag; 817 aic->msg_len = 2; 818 break; 819 case AIC_MSG_SDTR: 820 scb = aic->nexus; 821 ti = &aic->tinfo[scb->target]; 822 aic->msg_buf[0] = MSG_EXTENDED; 823 aic->msg_buf[1] = MSG_EXT_SDTR_LEN; 824 aic->msg_buf[2] = MSG_EXT_SDTR; 825 aic->msg_buf[3] = ti->goal.period; 826 aic->msg_buf[4] = ti->goal.offset; 827 aic->msg_len = MSG_EXT_SDTR_LEN + 2; 828 ti->flags |= TINFO_SDTR_SENT; 829 break; 830 case AIC_MSG_MSGBUF: 831 /* a single message already in the buffer */ 832 if (aic->msg_buf[0] == MSG_BUS_DEV_RESET || 833 aic->msg_buf[0] == MSG_ABORT || 834 aic->msg_buf[0] == MSG_ABORT_TAG) 835 aic->flags |= AIC_BUSFREE_OK; 836 break; 837 } 838 } 839 /* 840 * If this is the last message byte of all messages, 841 * clear ATNO to signal transmission complete. 842 */ 843 if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1) 844 aic_outb(aic, CLRSINT1, CLRATNO); 845 /* transmit the message byte */ 846 aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]); 847 } while (aic_spiordy(aic)); 848 849 aic_outb(aic, SXFRCTL0, CHEN); 850 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 851} 852 853/* 854 * Read data bytes. 855 */ 856static void 857aic_datain(struct aic_softc *aic) 858{ 859 struct aic_scb *scb = aic->nexus; 860 u_int8_t dmastat, dmacntrl0; 861 int n; 862 863 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_datain\n")); 864 865 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 866 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 867 868 dmacntrl0 = ENDMA; 869 if (aic->flags & AIC_DWIO_ENABLE) 870 dmacntrl0 |= DWORDPIO; 871 aic_outb(aic, DMACNTRL0, dmacntrl0); 872 873 while (scb->data_len > 0) { 874 for (;;) { 875 /* wait for the fifo to fill up or a phase change */ 876 dmastat = aic_inb(aic, DMASTAT); 877 if (dmastat & (INTSTAT|DFIFOFULL)) 878 break; 879 } 880 if (dmastat & DFIFOFULL) { 881 n = FIFOSIZE; 882 } else { 883 /* 884 * No more data, wait for the remaining bytes in 885 * the scsi fifo to be transfer to the host fifo. 886 */ 887 while (!(aic_inb(aic, SSTAT2) & SEMPTY)) 888 ; 889 n = aic_inb(aic, FIFOSTAT); 890 } 891 n = imin(scb->data_len, n); 892 if (aic->flags & AIC_DWIO_ENABLE) { 893 if (n >= 12) { 894 aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2); 895 scb->data_ptr += n & ~3; 896 scb->data_len -= n & ~3; 897 n &= 3; 898 } 899 } else { 900 if (n >= 8) { 901 aic_insw(aic, DMADATA, scb->data_ptr, n >> 1); 902 scb->data_ptr += n & ~1; 903 scb->data_len -= n & ~1; 904 n &= 1; 905 } 906 } 907 if (n) { 908 aic_outb(aic, DMACNTRL0, ENDMA|B8MODE); 909 aic_insb(aic, DMADATA, scb->data_ptr, n); 910 scb->data_ptr += n; 911 scb->data_len -= n; 912 aic_outb(aic, DMACNTRL0, dmacntrl0); 913 } 914 915 if (dmastat & INTSTAT) 916 break; 917 } 918 919 aic_outb(aic, SXFRCTL0, CHEN); 920 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 921} 922 923/* 924 * Send data bytes. 925 */ 926static void 927aic_dataout(struct aic_softc *aic) 928{ 929 struct aic_scb *scb = aic->nexus; 930 u_int8_t dmastat, dmacntrl0, sstat2; 931 int n; 932 933 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_dataout\n")); 934 935 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 936 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 937 938 dmacntrl0 = ENDMA|WRITE; 939 if (aic->flags & AIC_DWIO_ENABLE) 940 dmacntrl0 |= DWORDPIO; 941 aic_outb(aic, DMACNTRL0, dmacntrl0); 942 943 while (scb->data_len > 0) { 944 for (;;) { 945 /* wait for the fifo to clear up or a phase change */ 946 dmastat = aic_inb(aic, DMASTAT); 947 if (dmastat & (INTSTAT|DFIFOEMP)) 948 break; 949 } 950 if (dmastat & INTSTAT) 951 break; 952 n = imin(scb->data_len, FIFOSIZE); 953 if (aic->flags & AIC_DWIO_ENABLE) { 954 if (n >= 12) { 955 aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2); 956 scb->data_ptr += n & ~3; 957 scb->data_len -= n & ~3; 958 n &= 3; 959 } 960 } else { 961 if (n >= 8) { 962 aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1); 963 scb->data_ptr += n & ~1; 964 scb->data_len -= n & ~1; 965 n &= 1; 966 } 967 } 968 if (n) { 969 aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE); 970 aic_outsb(aic, DMADATA, scb->data_ptr, n); 971 scb->data_ptr += n; 972 scb->data_len -= n; 973 aic_outb(aic, DMACNTRL0, dmacntrl0); 974 } 975 } 976 977 for (;;) { 978 /* wait until all bytes in the fifos are transmitted */ 979 dmastat = aic_inb(aic, DMASTAT); 980 sstat2 = aic_inb(aic, SSTAT2); 981 if ((dmastat & DFIFOEMP) && (sstat2 & SEMPTY)) 982 break; 983 if (dmastat & INTSTAT) { 984 /* adjust for untransmitted bytes */ 985 n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf); 986 scb->data_ptr -= n; 987 scb->data_len += n; 988 /* clear the fifo */ 989 aic_outb(aic, SXFRCTL0, CHEN|CLRCH); 990 aic_outb(aic, DMACNTRL0, RSTFIFO); 991 break; 992 } 993 } 994 995 aic_outb(aic, SXFRCTL0, CHEN); 996 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 997} 998 999/* 1000 * Send the scsi command. 1001 */ 1002static void 1003aic_cmd(struct aic_softc *aic) 1004{ 1005 struct aic_scb *scb = aic->nexus; 1006 struct scsi_request_sense sense_cmd; 1007 1008 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_cmd\n")); 1009 1010 if (scb->flags & SCB_SENSE) { 1011 /* autosense request */ 1012 sense_cmd.opcode = REQUEST_SENSE; 1013 sense_cmd.byte2 = scb->lun << 5; 1014 sense_cmd.length = scb->ccb->csio.sense_len; 1015 sense_cmd.control = 0; 1016 sense_cmd.unused[0] = 0; 1017 sense_cmd.unused[1] = 0; 1018 scb->cmd_ptr = (u_int8_t *)&sense_cmd; 1019 scb->cmd_len = sizeof(sense_cmd); 1020 scb->data_ptr = (u_int8_t *)&scb->ccb->csio.sense_data; 1021 scb->data_len = scb->ccb->csio.sense_len; 1022 } 1023 1024 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 1025 aic_outb(aic, DMACNTRL0, ENDMA|WRITE); 1026 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 1027 aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, scb->cmd_len >> 1); 1028 while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 && 1029 (aic_inb(aic, DMASTAT) & INTSTAT) == 0) 1030 ; 1031 aic_outb(aic, SXFRCTL0, CHEN); 1032 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 1033} 1034 1035/* 1036 * Finish off a command. The caller is responsible to remove the ccb 1037 * from any queue. 1038 */ 1039static void 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, 1065 cam_sim_path(aic->sim), 1066 scb->target, 1067 CAM_LUN_WILDCARD); 1068 1069 if (error == CAM_REQ_CMP) { 1070 xpt_async(AC_SENT_BDR, path, NULL); 1071 xpt_free_path(path); 1072 } 1073 1074 ccb_h = TAILQ_FIRST(&aic->pending_ccbs); 1075 while (ccb_h != NULL) { 1076 struct aic_scb *pending_scb; 1077 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, 1057 cam_sim_path(aic->sim), 1058 scb->target, 1059 CAM_LUN_WILDCARD); 1060 1061 if (error == CAM_REQ_CMP) { 1062 xpt_async(AC_SENT_BDR, path, NULL); 1063 xpt_free_path(path); 1064 } 1065 1066 ccb_h = TAILQ_FIRST(&aic->pending_ccbs); 1067 while (ccb_h != NULL) { 1068 struct aic_scb *pending_scb; 1069 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); 1197 1198 sstat0 = aic_inb(aic, SSTAT0); 1199 sstat1 = aic_inb(aic, SSTAT1); 1200 1201 if ((sstat1 & SCSIRSTI) != 0) { 1202 /* a device-initiated bus reset */ 1203 aic_outb(aic, CLRSINT1, CLRSCSIRSTI); 1204 aic_reset(aic, /*initiate_reset*/FALSE); 1205 return; 1206 } 1207 1208 if ((sstat1 & SCSIPERR) != 0) { 1209 aic_outb(aic, CLRSINT1, CLRSCSIPERR); 1210 aic_sched_msgout(aic, MSG_PARITY_ERROR); 1211 aic_outb(aic, DMACNTRL0, INTEN); 1212 return; 1213 } 1214 1215 if (aic_inb(aic, SSTAT4)) { 1216 aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR); 1217 aic_reset(aic, /*initiate_reset*/TRUE); 1218 return; 1219 } 1220 1221 if (aic->state <= AIC_SELECTING) { 1222 if ((sstat0 & SELDI) != 0) { 1223 aic_reselected(aic); 1224 aic_outb(aic, DMACNTRL0, INTEN); 1225 return; 1226 } 1227 1228 if ((sstat0 & SELDO) != 0) { 1229 aic_selected(aic); 1230 aic_outb(aic, DMACNTRL0, INTEN); 1231 return; 1232 } 1233 1234 if ((sstat1 & SELTO) != 0) { 1235 scb = aic->nexus; 1236 ccb = scb->ccb; 1237 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1238 aic_done(aic, scb); 1239 while ((sstat1 & BUSFREE) == 0) 1240 sstat1 = aic_inb(aic, SSTAT1); 1241 aic->flags |= AIC_BUSFREE_OK; 1242 } 1243 } 1244 1245 if ((sstat1 & BUSFREE) != 0) { 1246 aic_outb(aic, SCSISEQ, 0); 1247 aic_outb(aic, CLRSINT0, sstat0); 1248 aic_outb(aic, CLRSINT1, sstat1); 1249 if ((scb = aic->nexus)) { 1250 if ((aic->flags & AIC_BUSFREE_OK) == 0) { 1251 ccb = scb->ccb; 1252 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 1253 aic_done(aic, scb); 1254 } else if (scb->flags & SCB_DEVICE_RESET) { 1255 ccb = scb->ccb; 1256 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 1257 xpt_async(AC_SENT_BDR, 1258 ccb->ccb_h.path, NULL); 1259 ccb->ccb_h.status |= CAM_REQ_CMP; 1260 } else 1261 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1262 aic_done(aic, scb); 1263 } else if (scb->flags & SCB_SENSE) { 1264 /* autosense request */ 1265 aic->flags &= ~AIC_BUSFREE_OK; 1266 aic->tinfo[scb->target].lubusy &= 1267 ~(1 << scb->lun); 1268 aic_select(aic); 1269 aic_outb(aic, DMACNTRL0, INTEN); 1270 return; 1271 } 1272 } 1273 aic->flags &= ~AIC_BUSFREE_OK; 1274 aic->state = AIC_IDLE; 1275 aic_start(aic); 1276 aic_outb(aic, DMACNTRL0, INTEN); 1277 return; 1278 } 1279 1280 if ((sstat1 & REQINIT) != 0) { 1281 u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK; 1282 aic_outb(aic, SCSISIGO, phase); 1283 aic_outb(aic, CLRSINT1, CLRPHASECHG); 1284 1285 switch (phase) { 1286 case PH_MSGOUT: 1287 aic_msgout(aic); 1288 break; 1289 case PH_MSGIN: 1290 aic_msgin(aic); 1291 break; 1292 case PH_STAT: 1293 scb = aic->nexus; 1294 ccb = scb->ccb; 1295 aic_outb(aic, DMACNTRL0, 0); 1296 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 1297 scb->status = aic_inb(aic, SCSIDAT); 1298 aic_outb(aic, SXFRCTL0, CHEN); 1299 break; 1300 case PH_CMD: 1301 aic_cmd(aic); 1302 break; 1303 case PH_DATAIN: 1304 aic_datain(aic); 1305 break; 1306 case PH_DATAOUT: 1307 aic_dataout(aic); 1308 break; 1309 } 1310 aic->prev_phase = phase; 1311 aic_outb(aic, DMACNTRL0, INTEN); 1312 return; 1313 } 1314 1315 printf("aic_intr: unexpected intr sstat0 %x sstat1 %x\n", 1316 sstat0, sstat1); 1317 aic_outb(aic, DMACNTRL0, INTEN); 1318} 1319 1320/* 1321 * Reset ourselves. 1322 */ 1323static void 1324aic_chip_reset(struct aic_softc *aic) 1325{ 1326 /* 1327 * Doc. recommends to clear these two registers before 1328 * operations commence 1329 */ 1330 aic_outb(aic, SCSITEST, 0); 1331 aic_outb(aic, TEST, 0); 1332 1333 /* Reset SCSI-FIFO and abort any transfers */ 1334 aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT); 1335 1336 /* Reset HOST-FIFO */ 1337 aic_outb(aic, DMACNTRL0, RSTFIFO); 1338 aic_outb(aic, DMACNTRL1, 0); 1339 1340 /* Disable all selection features */ 1341 aic_outb(aic, SCSISEQ, 0); 1342 aic_outb(aic, SXFRCTL1, 0); 1343 1344 /* Disable interrupts */ 1345 aic_outb(aic, SIMODE0, 0); 1346 aic_outb(aic, SIMODE1, 0); 1347 1348 /* Clear interrupts */ 1349 aic_outb(aic, CLRSINT0, 0x7f); 1350 aic_outb(aic, CLRSINT1, 0xef); 1351 1352 /* Disable synchronous transfers */ 1353 aic_outb(aic, SCSIRATE, 0); 1354 1355 /* Haven't seen ant errors (yet) */ 1356 aic_outb(aic, CLRSERR, 0x07); 1357 1358 /* Set our SCSI-ID */ 1359 aic_outb(aic, SCSIID, aic->initiator << OID_S); 1360 aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM); 1361} 1362 1363/* 1364 * Reset the SCSI bus 1365 */ 1366static void 1367aic_scsi_reset(struct aic_softc *aic) 1368{ 1369 aic_outb(aic, SCSISEQ, SCSIRSTO); 1370 DELAY(500); 1371 aic_outb(aic, SCSISEQ, 0); 1372 DELAY(50); 1373} 1374 1375/* 1376 * Reset. Abort all pending commands. 1377 */ 1378static void 1379aic_reset(struct aic_softc *aic, int initiate_reset) 1380{ 1381 struct ccb_hdr *ccb_h; 1382 1383 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reset\n")); 1384 1385 if (initiate_reset) 1386 aic_scsi_reset(aic); 1387 aic_chip_reset(aic); 1388 1389 xpt_async(AC_BUS_RESET, aic->path, NULL); 1390 1391 while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) { 1392 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe); 1393 ccb_h->status |= CAM_SCSI_BUS_RESET; 1394 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr); 1395 } 1396 1397 while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) { 1398 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 1399 ccb_h->status |= CAM_SCSI_BUS_RESET; 1400 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr); 1401 } 1402 1403 if (aic->nexus) { 1404 ccb_h = &aic->nexus->ccb->ccb_h; 1405 ccb_h->status |= CAM_SCSI_BUS_RESET; 1406 aic_done(aic, aic->nexus); 1407 } 1408 1409 aic->state = AIC_IDLE; 1410 aic_outb(aic, DMACNTRL0, INTEN); 1411} 1412 1413static char *aic_chip_names[] = { 1414 "AIC6260", "AIC6360", "AIC6370", "GM82C700", 1415}; 1416 1417static struct { 1418 int type; 1419 char *idstring; 1420} aic_chip_ids[] = { 1421 { AIC6360, IDSTRING_AIC6360 }, 1422 { AIC6370, IDSTRING_AIC6370 }, 1423 { GM82C700, IDSTRING_GM82C700 }, 1424}; 1425 1426static void 1427aic_init(struct aic_softc *aic) 1428{ 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); 1193 1194 sstat0 = aic_inb(aic, SSTAT0); 1195 sstat1 = aic_inb(aic, SSTAT1); 1196 1197 if ((sstat1 & SCSIRSTI) != 0) { 1198 /* a device-initiated bus reset */ 1199 aic_outb(aic, CLRSINT1, CLRSCSIRSTI); 1200 aic_reset(aic, /*initiate_reset*/FALSE); 1201 return; 1202 } 1203 1204 if ((sstat1 & SCSIPERR) != 0) { 1205 aic_outb(aic, CLRSINT1, CLRSCSIPERR); 1206 aic_sched_msgout(aic, MSG_PARITY_ERROR); 1207 aic_outb(aic, DMACNTRL0, INTEN); 1208 return; 1209 } 1210 1211 if (aic_inb(aic, SSTAT4)) { 1212 aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR); 1213 aic_reset(aic, /*initiate_reset*/TRUE); 1214 return; 1215 } 1216 1217 if (aic->state <= AIC_SELECTING) { 1218 if ((sstat0 & SELDI) != 0) { 1219 aic_reselected(aic); 1220 aic_outb(aic, DMACNTRL0, INTEN); 1221 return; 1222 } 1223 1224 if ((sstat0 & SELDO) != 0) { 1225 aic_selected(aic); 1226 aic_outb(aic, DMACNTRL0, INTEN); 1227 return; 1228 } 1229 1230 if ((sstat1 & SELTO) != 0) { 1231 scb = aic->nexus; 1232 ccb = scb->ccb; 1233 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1234 aic_done(aic, scb); 1235 while ((sstat1 & BUSFREE) == 0) 1236 sstat1 = aic_inb(aic, SSTAT1); 1237 aic->flags |= AIC_BUSFREE_OK; 1238 } 1239 } 1240 1241 if ((sstat1 & BUSFREE) != 0) { 1242 aic_outb(aic, SCSISEQ, 0); 1243 aic_outb(aic, CLRSINT0, sstat0); 1244 aic_outb(aic, CLRSINT1, sstat1); 1245 if ((scb = aic->nexus)) { 1246 if ((aic->flags & AIC_BUSFREE_OK) == 0) { 1247 ccb = scb->ccb; 1248 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 1249 aic_done(aic, scb); 1250 } else if (scb->flags & SCB_DEVICE_RESET) { 1251 ccb = scb->ccb; 1252 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 1253 xpt_async(AC_SENT_BDR, 1254 ccb->ccb_h.path, NULL); 1255 ccb->ccb_h.status |= CAM_REQ_CMP; 1256 } else 1257 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1258 aic_done(aic, scb); 1259 } else if (scb->flags & SCB_SENSE) { 1260 /* autosense request */ 1261 aic->flags &= ~AIC_BUSFREE_OK; 1262 aic->tinfo[scb->target].lubusy &= 1263 ~(1 << scb->lun); 1264 aic_select(aic); 1265 aic_outb(aic, DMACNTRL0, INTEN); 1266 return; 1267 } 1268 } 1269 aic->flags &= ~AIC_BUSFREE_OK; 1270 aic->state = AIC_IDLE; 1271 aic_start(aic); 1272 aic_outb(aic, DMACNTRL0, INTEN); 1273 return; 1274 } 1275 1276 if ((sstat1 & REQINIT) != 0) { 1277 u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK; 1278 aic_outb(aic, SCSISIGO, phase); 1279 aic_outb(aic, CLRSINT1, CLRPHASECHG); 1280 1281 switch (phase) { 1282 case PH_MSGOUT: 1283 aic_msgout(aic); 1284 break; 1285 case PH_MSGIN: 1286 aic_msgin(aic); 1287 break; 1288 case PH_STAT: 1289 scb = aic->nexus; 1290 ccb = scb->ccb; 1291 aic_outb(aic, DMACNTRL0, 0); 1292 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 1293 scb->status = aic_inb(aic, SCSIDAT); 1294 aic_outb(aic, SXFRCTL0, CHEN); 1295 break; 1296 case PH_CMD: 1297 aic_cmd(aic); 1298 break; 1299 case PH_DATAIN: 1300 aic_datain(aic); 1301 break; 1302 case PH_DATAOUT: 1303 aic_dataout(aic); 1304 break; 1305 } 1306 aic->prev_phase = phase; 1307 aic_outb(aic, DMACNTRL0, INTEN); 1308 return; 1309 } 1310 1311 printf("aic_intr: unexpected intr sstat0 %x sstat1 %x\n", 1312 sstat0, sstat1); 1313 aic_outb(aic, DMACNTRL0, INTEN); 1314} 1315 1316/* 1317 * Reset ourselves. 1318 */ 1319static void 1320aic_chip_reset(struct aic_softc *aic) 1321{ 1322 /* 1323 * Doc. recommends to clear these two registers before 1324 * operations commence 1325 */ 1326 aic_outb(aic, SCSITEST, 0); 1327 aic_outb(aic, TEST, 0); 1328 1329 /* Reset SCSI-FIFO and abort any transfers */ 1330 aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT); 1331 1332 /* Reset HOST-FIFO */ 1333 aic_outb(aic, DMACNTRL0, RSTFIFO); 1334 aic_outb(aic, DMACNTRL1, 0); 1335 1336 /* Disable all selection features */ 1337 aic_outb(aic, SCSISEQ, 0); 1338 aic_outb(aic, SXFRCTL1, 0); 1339 1340 /* Disable interrupts */ 1341 aic_outb(aic, SIMODE0, 0); 1342 aic_outb(aic, SIMODE1, 0); 1343 1344 /* Clear interrupts */ 1345 aic_outb(aic, CLRSINT0, 0x7f); 1346 aic_outb(aic, CLRSINT1, 0xef); 1347 1348 /* Disable synchronous transfers */ 1349 aic_outb(aic, SCSIRATE, 0); 1350 1351 /* Haven't seen ant errors (yet) */ 1352 aic_outb(aic, CLRSERR, 0x07); 1353 1354 /* Set our SCSI-ID */ 1355 aic_outb(aic, SCSIID, aic->initiator << OID_S); 1356 aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM); 1357} 1358 1359/* 1360 * Reset the SCSI bus 1361 */ 1362static void 1363aic_scsi_reset(struct aic_softc *aic) 1364{ 1365 aic_outb(aic, SCSISEQ, SCSIRSTO); 1366 DELAY(500); 1367 aic_outb(aic, SCSISEQ, 0); 1368 DELAY(50); 1369} 1370 1371/* 1372 * Reset. Abort all pending commands. 1373 */ 1374static void 1375aic_reset(struct aic_softc *aic, int initiate_reset) 1376{ 1377 struct ccb_hdr *ccb_h; 1378 1379 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reset\n")); 1380 1381 if (initiate_reset) 1382 aic_scsi_reset(aic); 1383 aic_chip_reset(aic); 1384 1385 xpt_async(AC_BUS_RESET, aic->path, NULL); 1386 1387 while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) { 1388 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe); 1389 ccb_h->status |= CAM_SCSI_BUS_RESET; 1390 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr); 1391 } 1392 1393 while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) { 1394 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 1395 ccb_h->status |= CAM_SCSI_BUS_RESET; 1396 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr); 1397 } 1398 1399 if (aic->nexus) { 1400 ccb_h = &aic->nexus->ccb->ccb_h; 1401 ccb_h->status |= CAM_SCSI_BUS_RESET; 1402 aic_done(aic, aic->nexus); 1403 } 1404 1405 aic->state = AIC_IDLE; 1406 aic_outb(aic, DMACNTRL0, INTEN); 1407} 1408 1409static char *aic_chip_names[] = { 1410 "AIC6260", "AIC6360", "AIC6370", "GM82C700", 1411}; 1412 1413static struct { 1414 int type; 1415 char *idstring; 1416} aic_chip_ids[] = { 1417 { AIC6360, IDSTRING_AIC6360 }, 1418 { AIC6370, IDSTRING_AIC6370 }, 1419 { GM82C700, IDSTRING_GM82C700 }, 1420}; 1421 1422static void 1423aic_init(struct aic_softc *aic) 1424{ 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 1445 /* determine the chip type from its ID string */ 1446 aic->chip_type = AIC6260; 1447 aic_insb(aic, ID, chip_id, sizeof(chip_id) - 1); 1448 chip_id[sizeof(chip_id) - 1] = '\0'; 1449 for (i = 0; i < sizeof(aic_chip_ids) / sizeof(aic_chip_ids[0]); i++) { 1450 if (!strcmp(chip_id, aic_chip_ids[i].idstring)) { 1451 aic->chip_type = aic_chip_ids[i].type; 1452 break; 1453 } 1454 } 1455 1456 porta = aic_inb(aic, PORTA); 1457 portb = aic_inb(aic, PORTB); 1458 1459 aic->initiator = PORTA_ID(porta); 1460 if (PORTA_PARITY(porta)) 1461 aic->flags |= AIC_PARITY_ENABLE; 1462 if (PORTB_DISC(portb)) 1463 aic->flags |= AIC_DISC_ENABLE; 1464 if (PORTB_DMA(portb)) 1465 aic->flags |= AIC_DMA_ENABLE; 1466 1467 /* 1468 * We can do fast SCSI (10MHz clock rate) if bit 4 of portb 1469 * is set and we've got a 6360. The 6260 can only do standard 1470 * 5MHz SCSI. 1471 */ 1472 if (aic->chip_type > AIC6260 || aic_inb(aic, REV)) { 1473 if (PORTB_FSYNC(portb)) 1474 aic->flags |= AIC_FAST_ENABLE; 1475 aic->flags |= AIC_DWIO_ENABLE; 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 1442 /* determine the chip type from its ID string */ 1443 aic->chip_type = AIC6260; 1444 aic_insb(aic, ID, chip_id, sizeof(chip_id) - 1); 1445 chip_id[sizeof(chip_id) - 1] = '\0'; 1446 for (i = 0; i < sizeof(aic_chip_ids) / sizeof(aic_chip_ids[0]); i++) { 1447 if (!strcmp(chip_id, aic_chip_ids[i].idstring)) { 1448 aic->chip_type = aic_chip_ids[i].type; 1449 break; 1450 } 1451 } 1452 1453 porta = aic_inb(aic, PORTA); 1454 portb = aic_inb(aic, PORTB); 1455 1456 aic->initiator = PORTA_ID(porta); 1457 if (PORTA_PARITY(porta)) 1458 aic->flags |= AIC_PARITY_ENABLE; 1459 if (PORTB_DISC(portb)) 1460 aic->flags |= AIC_DISC_ENABLE; 1461 if (PORTB_DMA(portb)) 1462 aic->flags |= AIC_DMA_ENABLE; 1463 1464 /* 1465 * We can do fast SCSI (10MHz clock rate) if bit 4 of portb 1466 * is set and we've got a 6360. The 6260 can only do standard 1467 * 5MHz SCSI. 1468 */ 1469 if (aic->chip_type > AIC6260 || aic_inb(aic, REV)) { 1470 if (PORTB_FSYNC(portb)) 1471 aic->flags |= AIC_FAST_ENABLE; 1472 aic->flags |= AIC_DWIO_ENABLE; 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)); 1496 ti->flags = TINFO_TAG_ENB; 1497 if (aic->flags & AIC_DISC_ENABLE) 1498 ti->flags |= TINFO_DISC_ENB; 1499 ti->user.period = aic->max_period; 1500 ti->user.offset = AIC_SYNC_OFFSET; 1501 ti->scsirate = 0; 1502 } 1503 1504 aic_outb(aic, DMACNTRL0, INTEN); 1505} 1506 1507int 1508aic_probe(struct aic_softc *aic) 1509{ 1510 int i; 1511 1512 /* Remove aic6360 from possible powerdown mode */ 1513 aic_outb(aic, DMACNTRL0, 0); 1514 1515#define STSIZE 16 1516 aic_outb(aic, DMACNTRL1, 0); /* Reset stack pointer */ 1517 for (i = 0; i < STSIZE; i++) 1518 aic_outb(aic, STACK, i); 1519 1520 /* See if we can pull out the same sequence */ 1521 aic_outb(aic, DMACNTRL1, 0); 1522 for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++) 1523 ; 1524 if (i != STSIZE) 1525 return (ENXIO); 1526#undef STSIZE 1527 return (0); 1528} 1529 1530int 1531aic_attach(struct aic_softc *aic) 1532{ 1533 struct cam_devq *devq; 1534 1535 /* 1536 * Create the device queue for our SIM. 1537 */ 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)); 1493 ti->flags = TINFO_TAG_ENB; 1494 if (aic->flags & AIC_DISC_ENABLE) 1495 ti->flags |= TINFO_DISC_ENB; 1496 ti->user.period = aic->max_period; 1497 ti->user.offset = AIC_SYNC_OFFSET; 1498 ti->scsirate = 0; 1499 } 1500 1501 aic_outb(aic, DMACNTRL0, INTEN); 1502} 1503 1504int 1505aic_probe(struct aic_softc *aic) 1506{ 1507 int i; 1508 1509 /* Remove aic6360 from possible powerdown mode */ 1510 aic_outb(aic, DMACNTRL0, 0); 1511 1512#define STSIZE 16 1513 aic_outb(aic, DMACNTRL1, 0); /* Reset stack pointer */ 1514 for (i = 0; i < STSIZE; i++) 1515 aic_outb(aic, STACK, i); 1516 1517 /* See if we can pull out the same sequence */ 1518 aic_outb(aic, DMACNTRL1, 0); 1519 for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++) 1520 ; 1521 if (i != STSIZE) 1522 return (ENXIO); 1523#undef STSIZE 1524 return (0); 1525} 1526 1527int 1528aic_attach(struct aic_softc *aic) 1529{ 1530 struct cam_devq *devq; 1531 1532 /* 1533 * Create the device queue for our SIM. 1534 */ 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}
|