1 /* 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010 LSI Corp. 5 * All rights reserved. 6 * Author : Manjunath Ranganathaiah <manjunath.ranganathaiah@lsi.com> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <dev/tws/tws.h> 33 #include <dev/tws/tws_services.h> 34 #include <dev/tws/tws_hdm.h> 35 #include <dev/tws/tws_user.h> 36 #include <cam/cam.h> 37 #include <cam/cam_ccb.h> 38 #include <cam/cam_sim.h> 39 #include <cam/cam_xpt_sim.h> 40 #include <cam/cam_debug.h> 41 #include <cam/cam_periph.h> 42 43 #include <cam/scsi/scsi_all.h> 44 #include <cam/scsi/scsi_message.h> 45 46 static int tws_cam_depth=(TWS_MAX_REQS - TWS_RESERVED_REQS); 47 static char tws_sev_str[5][8]={"","ERROR","WARNING","INFO","DEBUG"}; 48 49 static void tws_action(struct cam_sim *sim, union ccb *ccb); 50 static void tws_poll(struct cam_sim *sim); 51 static void tws_scsi_complete(struct tws_request *req); 52 53 void tws_unmap_request(struct tws_softc *sc, struct tws_request *req); 54 int32_t tws_map_request(struct tws_softc *sc, struct tws_request *req); 55 int tws_bus_scan(struct tws_softc *sc); 56 int tws_cam_attach(struct tws_softc *sc); 57 void tws_cam_detach(struct tws_softc *sc); 58 void tws_reset(void *arg); 59 60 static void tws_reset_cb(void *arg); 61 static void tws_reinit(void *arg); 62 static int32_t tws_execute_scsi(struct tws_softc *sc, union ccb *ccb); 63 static void tws_freeze_simq(struct tws_softc *sc, struct tws_request *req); 64 static void tws_dmamap_data_load_cbfn(void *arg, bus_dma_segment_t *segs, 65 int nseg, int error); 66 static void tws_fill_sg_list(struct tws_softc *sc, void *sgl_src, 67 void *sgl_dest, u_int16_t num_sgl_entries); 68 static void tws_err_complete(struct tws_softc *sc, u_int64_t mfa); 69 static void tws_scsi_err_complete(struct tws_request *req, 70 struct tws_command_header *hdr); 71 static void tws_passthru_err_complete(struct tws_request *req, 72 struct tws_command_header *hdr); 73 74 void tws_timeout(void *arg); 75 static void tws_intr_attn_aen(struct tws_softc *sc); 76 static void tws_intr_attn_error(struct tws_softc *sc); 77 static void tws_intr_resp(struct tws_softc *sc); 78 void tws_intr(void *arg); 79 void tws_cmd_complete(struct tws_request *req); 80 void tws_aen_complete(struct tws_request *req); 81 int tws_send_scsi_cmd(struct tws_softc *sc, int cmd); 82 void tws_getset_param_complete(struct tws_request *req); 83 int tws_set_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 84 u_int32_t param_size, void *data); 85 int tws_get_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 86 u_int32_t param_size, void *data); 87 88 extern struct tws_request *tws_get_request(struct tws_softc *sc, 89 u_int16_t type); 90 extern void *tws_release_request(struct tws_request *req); 91 extern int tws_submit_command(struct tws_softc *sc, struct tws_request *req); 92 extern boolean tws_get_response(struct tws_softc *sc, 93 u_int16_t *req_id, u_int64_t *mfa); 94 extern void tws_q_insert_tail(struct tws_softc *sc, struct tws_request *req, 95 u_int8_t q_type ); 96 extern struct tws_request * tws_q_remove_request(struct tws_softc *sc, 97 struct tws_request *req, u_int8_t q_type ); 98 extern void tws_send_event(struct tws_softc *sc, u_int8_t event); 99 100 extern struct tws_sense * 101 tws_find_sense_from_mfa(struct tws_softc *sc, u_int64_t mfa); 102 103 extern void tws_fetch_aen(void *arg); 104 extern void tws_disable_db_intr(struct tws_softc *sc); 105 extern void tws_enable_db_intr(struct tws_softc *sc); 106 extern void tws_passthru_complete(struct tws_request *req); 107 extern void tws_aen_synctime_with_host(struct tws_softc *sc); 108 extern void tws_circular_aenq_insert(struct tws_softc *sc, 109 struct tws_circular_q *cq, struct tws_event_packet *aen); 110 extern int tws_use_32bit_sgls; 111 extern boolean tws_ctlr_reset(struct tws_softc *sc); 112 extern struct tws_request * tws_q_remove_tail(struct tws_softc *sc, 113 u_int8_t q_type ); 114 extern void tws_turn_off_interrupts(struct tws_softc *sc); 115 extern void tws_turn_on_interrupts(struct tws_softc *sc); 116 extern int tws_init_connect(struct tws_softc *sc, u_int16_t mc); 117 extern void tws_init_obfl_q(struct tws_softc *sc); 118 extern uint8_t tws_get_state(struct tws_softc *sc); 119 extern void tws_assert_soft_reset(struct tws_softc *sc); 120 extern boolean tws_ctlr_ready(struct tws_softc *sc); 121 extern u_int16_t tws_poll4_response(struct tws_softc *sc, u_int64_t *mfa); 122 extern int tws_setup_intr(struct tws_softc *sc, int irqs); 123 extern int tws_teardown_intr(struct tws_softc *sc); 124 125 int 126 tws_cam_attach(struct tws_softc *sc) 127 { 128 struct cam_devq *devq; 129 130 TWS_TRACE_DEBUG(sc, "entry", 0, sc); 131 /* Create a device queue for sim */ 132 133 /* 134 * if the user sets cam depth to less than 1 135 * cam may get confused 136 */ 137 if ( tws_cam_depth < 1 ) 138 tws_cam_depth = 1; 139 if ( tws_cam_depth > (tws_queue_depth - TWS_RESERVED_REQS) ) 140 tws_cam_depth = tws_queue_depth - TWS_RESERVED_REQS; 141 142 TWS_TRACE_DEBUG(sc, "depths,ctlr,cam", tws_queue_depth, tws_cam_depth); 143 144 if ((devq = cam_simq_alloc(tws_cam_depth)) == NULL) { 145 tws_log(sc, CAM_SIMQ_ALLOC); 146 return(ENOMEM); 147 } 148 149 /* 150 * Create a SIM entry. Though we can support tws_cam_depth 151 * simultaneous requests, we claim to be able to handle only 152 * (tws_cam_depth), so that we always have reserved requests 153 * packet available to service ioctls and internal commands. 154 */ 155 sc->sim = cam_sim_alloc(tws_action, tws_poll, "tws", sc, 156 device_get_unit(sc->tws_dev), 157 &sc->sim_lock, 158 tws_cam_depth, 1, devq); 159 /* 1, 1, devq); */ 160 if (sc->sim == NULL) { 161 cam_simq_free(devq); 162 tws_log(sc, CAM_SIM_ALLOC); 163 } 164 /* Register the bus. */ 165 mtx_lock(&sc->sim_lock); 166 if (xpt_bus_register(sc->sim, 167 sc->tws_dev, 168 0) != CAM_SUCCESS) { 169 cam_sim_free(sc->sim, TRUE); /* passing true will free the devq */ 170 sc->sim = NULL; /* so cam_detach will not try to free it */ 171 mtx_unlock(&sc->sim_lock); 172 tws_log(sc, TWS_XPT_BUS_REGISTER); 173 return(ENXIO); 174 } 175 if (xpt_create_path(&sc->path, NULL, cam_sim_path(sc->sim), 176 CAM_TARGET_WILDCARD, 177 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 178 xpt_bus_deregister(cam_sim_path(sc->sim)); 179 /* Passing TRUE to cam_sim_free will free the devq as well. */ 180 cam_sim_free(sc->sim, TRUE); 181 tws_log(sc, TWS_XPT_CREATE_PATH); 182 mtx_unlock(&sc->sim_lock); 183 return(ENXIO); 184 } 185 mtx_unlock(&sc->sim_lock); 186 187 return(0); 188 } 189 190 void 191 tws_cam_detach(struct tws_softc *sc) 192 { 193 TWS_TRACE_DEBUG(sc, "entry", 0, 0); 194 mtx_lock(&sc->sim_lock); 195 if (sc->path) 196 xpt_free_path(sc->path); 197 if (sc->sim) { 198 xpt_bus_deregister(cam_sim_path(sc->sim)); 199 cam_sim_free(sc->sim, TRUE); 200 } 201 mtx_unlock(&sc->sim_lock); 202 } 203 204 int 205 tws_bus_scan(struct tws_softc *sc) 206 { 207 union ccb *ccb; 208 209 TWS_TRACE_DEBUG(sc, "entry", sc, 0); 210 if (!(sc->sim)) 211 return(ENXIO); 212 ccb = xpt_alloc_ccb(); 213 mtx_lock(&sc->sim_lock); 214 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim), 215 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 216 mtx_unlock(&sc->sim_lock); 217 xpt_free_ccb(ccb); 218 return(EIO); 219 } 220 xpt_rescan(ccb); 221 mtx_unlock(&sc->sim_lock); 222 return(0); 223 } 224 225 static void 226 tws_action(struct cam_sim *sim, union ccb *ccb) 227 { 228 struct tws_softc *sc = (struct tws_softc *)cam_sim_softc(sim); 229 230 switch( ccb->ccb_h.func_code ) { 231 case XPT_SCSI_IO: 232 { 233 if ( tws_execute_scsi(sc, ccb) ) 234 TWS_TRACE_DEBUG(sc, "execute scsi failed", 0, 0); 235 break; 236 } 237 case XPT_ABORT: 238 { 239 TWS_TRACE_DEBUG(sc, "abort i/o", 0, 0); 240 ccb->ccb_h.status = CAM_UA_ABORT; 241 xpt_done(ccb); 242 break; 243 } 244 case XPT_RESET_BUS: 245 { 246 TWS_TRACE_DEBUG(sc, "reset bus", sim, ccb); 247 break; 248 } 249 case XPT_SET_TRAN_SETTINGS: 250 { 251 TWS_TRACE_DEBUG(sc, "set tran settings", sim, ccb); 252 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 253 xpt_done(ccb); 254 255 break; 256 } 257 case XPT_GET_TRAN_SETTINGS: 258 { 259 TWS_TRACE_DEBUG(sc, "get tran settings", sim, ccb); 260 261 ccb->cts.protocol = PROTO_SCSI; 262 ccb->cts.protocol_version = SCSI_REV_2; 263 ccb->cts.transport = XPORT_SPI; 264 ccb->cts.transport_version = 2; 265 266 ccb->cts.xport_specific.spi.valid = CTS_SPI_VALID_DISC; 267 ccb->cts.xport_specific.spi.flags = CTS_SPI_FLAGS_DISC_ENB; 268 ccb->cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ; 269 ccb->cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB; 270 ccb->ccb_h.status = CAM_REQ_CMP; 271 xpt_done(ccb); 272 273 break; 274 } 275 case XPT_CALC_GEOMETRY: 276 { 277 TWS_TRACE_DEBUG(sc, "calc geometry(ccb,block-size)", ccb, 278 ccb->ccg.block_size); 279 cam_calc_geometry(&ccb->ccg, 1/* extended */); 280 xpt_done(ccb); 281 282 break; 283 } 284 case XPT_PATH_INQ: 285 { 286 TWS_TRACE_DEBUG(sc, "path inquiry", sim, ccb); 287 ccb->cpi.version_num = 1; 288 ccb->cpi.hba_inquiry = 0; 289 ccb->cpi.target_sprt = 0; 290 ccb->cpi.hba_misc = 0; 291 ccb->cpi.hba_eng_cnt = 0; 292 ccb->cpi.max_target = TWS_MAX_NUM_UNITS; 293 ccb->cpi.max_lun = TWS_MAX_NUM_LUNS - 1; 294 ccb->cpi.unit_number = cam_sim_unit(sim); 295 ccb->cpi.bus_id = cam_sim_bus(sim); 296 ccb->cpi.initiator_id = TWS_SCSI_INITIATOR_ID; 297 ccb->cpi.base_transfer_speed = 6000000; 298 strlcpy(ccb->cpi.sim_vid, "FreeBSD", SIM_IDLEN); 299 strlcpy(ccb->cpi.hba_vid, "3ware", HBA_IDLEN); 300 strlcpy(ccb->cpi.dev_name, cam_sim_name(sim), DEV_IDLEN); 301 ccb->cpi.transport = XPORT_SPI; 302 ccb->cpi.transport_version = 2; 303 ccb->cpi.protocol = PROTO_SCSI; 304 ccb->cpi.protocol_version = SCSI_REV_2; 305 ccb->cpi.maxio = TWS_MAX_IO_SIZE; 306 ccb->ccb_h.status = CAM_REQ_CMP; 307 xpt_done(ccb); 308 309 break; 310 } 311 default: 312 TWS_TRACE_DEBUG(sc, "default", sim, ccb); 313 ccb->ccb_h.status = CAM_REQ_INVALID; 314 xpt_done(ccb); 315 break; 316 } 317 } 318 319 static void 320 tws_scsi_complete(struct tws_request *req) 321 { 322 struct tws_softc *sc = req->sc; 323 324 mtx_lock(&sc->q_lock); 325 tws_q_remove_request(sc, req, TWS_BUSY_Q); 326 mtx_unlock(&sc->q_lock); 327 328 callout_stop(&req->timeout); 329 tws_unmap_request(req->sc, req); 330 331 req->ccb_ptr->ccb_h.status = CAM_REQ_CMP; 332 mtx_lock(&sc->sim_lock); 333 xpt_done(req->ccb_ptr); 334 mtx_unlock(&sc->sim_lock); 335 336 mtx_lock(&sc->q_lock); 337 tws_q_insert_tail(sc, req, TWS_FREE_Q); 338 mtx_unlock(&sc->q_lock); 339 } 340 341 void 342 tws_getset_param_complete(struct tws_request *req) 343 { 344 struct tws_softc *sc = req->sc; 345 346 TWS_TRACE_DEBUG(sc, "getset complete", req, req->request_id); 347 348 callout_stop(&req->timeout); 349 tws_unmap_request(sc, req); 350 351 free(req->data, M_TWS); 352 353 req->state = TWS_REQ_STATE_FREE; 354 } 355 356 void 357 tws_aen_complete(struct tws_request *req) 358 { 359 struct tws_softc *sc = req->sc; 360 struct tws_command_header *sense; 361 struct tws_event_packet event; 362 u_int16_t aen_code=0; 363 364 TWS_TRACE_DEBUG(sc, "aen complete", 0, req->request_id); 365 366 callout_stop(&req->timeout); 367 tws_unmap_request(sc, req); 368 369 sense = (struct tws_command_header *)req->data; 370 371 TWS_TRACE_DEBUG(sc,"sense code, key",sense->sense_data[0], 372 sense->sense_data[2]); 373 TWS_TRACE_DEBUG(sc,"sense rid, seve",sense->header_desc.request_id, 374 sense->status_block.res__severity); 375 TWS_TRACE_DEBUG(sc,"sense srcnum, error",sense->status_block.srcnum, 376 sense->status_block.error); 377 TWS_TRACE_DEBUG(sc,"sense shdr, ssense",sense->header_desc.size_header, 378 sense->header_desc.size_sense); 379 380 aen_code = sense->status_block.error; 381 382 switch ( aen_code ) { 383 case TWS_AEN_SYNC_TIME_WITH_HOST : 384 tws_aen_synctime_with_host(sc); 385 break; 386 case TWS_AEN_QUEUE_EMPTY : 387 break; 388 default : 389 bzero(&event, sizeof(struct tws_event_packet)); 390 event.sequence_id = sc->seq_id; 391 event.time_stamp_sec = (u_int32_t)TWS_LOCAL_TIME; 392 event.aen_code = sense->status_block.error; 393 event.severity = sense->status_block.res__severity & 0x7; 394 event.event_src = TWS_SRC_CTRL_EVENT; 395 strcpy(event.severity_str, tws_sev_str[event.severity]); 396 event.retrieved = TWS_AEN_NOT_RETRIEVED; 397 398 bcopy(sense->err_specific_desc, event.parameter_data, 399 TWS_ERROR_SPECIFIC_DESC_LEN); 400 event.parameter_data[TWS_ERROR_SPECIFIC_DESC_LEN - 1] = '\0'; 401 event.parameter_len = (u_int8_t)strlen(event.parameter_data)+1; 402 403 if ( event.parameter_len < TWS_ERROR_SPECIFIC_DESC_LEN ) { 404 event.parameter_len += ((u_int8_t)strlen(event.parameter_data + 405 event.parameter_len) + 1); 406 } 407 408 device_printf(sc->tws_dev, "%s: (0x%02X: 0x%04X): %s: %s\n", 409 event.severity_str, 410 event.event_src, 411 event.aen_code, 412 event.parameter_data + 413 (strlen(event.parameter_data) + 1), 414 event.parameter_data); 415 416 mtx_lock(&sc->gen_lock); 417 tws_circular_aenq_insert(sc, &sc->aen_q, &event); 418 sc->seq_id++; 419 mtx_unlock(&sc->gen_lock); 420 break; 421 } 422 423 free(req->data, M_TWS); 424 425 req->state = TWS_REQ_STATE_FREE; 426 427 if ( aen_code != TWS_AEN_QUEUE_EMPTY ) { 428 /* timeout(tws_fetch_aen, sc, 1);*/ 429 sc->stats.num_aens++; 430 tws_fetch_aen((void *)sc); 431 } 432 } 433 434 void 435 tws_cmd_complete(struct tws_request *req) 436 { 437 struct tws_softc *sc = req->sc; 438 439 callout_stop(&req->timeout); 440 tws_unmap_request(sc, req); 441 } 442 443 static void 444 tws_err_complete(struct tws_softc *sc, u_int64_t mfa) 445 { 446 struct tws_command_header *hdr; 447 struct tws_sense *sen; 448 struct tws_request *req; 449 u_int16_t req_id; 450 u_int32_t reg, status; 451 452 if ( !mfa ) { 453 TWS_TRACE_DEBUG(sc, "null mfa", 0, mfa); 454 return; 455 } else { 456 /* lookup the sense */ 457 sen = tws_find_sense_from_mfa(sc, mfa); 458 if ( sen == NULL ) { 459 TWS_TRACE_DEBUG(sc, "found null req", 0, mfa); 460 return; 461 } 462 hdr = sen->hdr; 463 TWS_TRACE_DEBUG(sc, "sen, hdr", sen, hdr); 464 req_id = hdr->header_desc.request_id; 465 req = &sc->reqs[req_id]; 466 TWS_TRACE_DEBUG(sc, "req, id", req, req_id); 467 if ( req->error_code != TWS_REQ_RET_SUBMIT_SUCCESS ) 468 TWS_TRACE_DEBUG(sc, "submit failure?", 0, req->error_code); 469 } 470 471 switch (req->type) { 472 case TWS_REQ_TYPE_PASSTHRU : 473 tws_passthru_err_complete(req, hdr); 474 break; 475 case TWS_REQ_TYPE_GETSET_PARAM : 476 tws_getset_param_complete(req); 477 break; 478 case TWS_REQ_TYPE_SCSI_IO : 479 tws_scsi_err_complete(req, hdr); 480 break; 481 482 } 483 484 mtx_lock(&sc->io_lock); 485 hdr->header_desc.size_header = 128; 486 reg = (u_int32_t)( mfa>>32); 487 tws_write_reg(sc, TWS_I2O0_HOBQPH, reg, 4); 488 reg = (u_int32_t)(mfa); 489 tws_write_reg(sc, TWS_I2O0_HOBQPL, reg, 4); 490 491 status = tws_read_reg(sc, TWS_I2O0_STATUS, 4); 492 if ( status & TWS_BIT13 ) { 493 device_printf(sc->tws_dev, "OBFL Overrun\n"); 494 sc->obfl_q_overrun = true; 495 } 496 mtx_unlock(&sc->io_lock); 497 } 498 499 static void 500 tws_scsi_err_complete(struct tws_request *req, struct tws_command_header *hdr) 501 { 502 u_int8_t *sense_data; 503 struct tws_softc *sc = req->sc; 504 union ccb *ccb = req->ccb_ptr; 505 506 TWS_TRACE_DEBUG(sc, "sbe, cmd_status", hdr->status_block.error, 507 req->cmd_pkt->cmd.pkt_a.status); 508 if ( hdr->status_block.error == TWS_ERROR_LOGICAL_UNIT_NOT_SUPPORTED || 509 hdr->status_block.error == TWS_ERROR_UNIT_OFFLINE ) { 510 if ( ccb->ccb_h.target_lun ) { 511 TWS_TRACE_DEBUG(sc, "invalid lun error",0,0); 512 ccb->ccb_h.status |= CAM_DEV_NOT_THERE; 513 } else { 514 TWS_TRACE_DEBUG(sc, "invalid target error",0,0); 515 ccb->ccb_h.status |= CAM_SEL_TIMEOUT; 516 } 517 518 } else { 519 TWS_TRACE_DEBUG(sc, "scsi status error",0,0); 520 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 521 if (((ccb->csio.cdb_io.cdb_bytes[0] == 0x1A) && 522 (hdr->status_block.error == TWS_ERROR_NOT_SUPPORTED))) { 523 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; 524 TWS_TRACE_DEBUG(sc, "page mode not supported",0,0); 525 } 526 } 527 528 /* if there were no error simply mark complete error */ 529 if (ccb->ccb_h.status == 0) 530 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 531 532 sense_data = (u_int8_t *)&ccb->csio.sense_data; 533 if (sense_data) { 534 memcpy(sense_data, hdr->sense_data, TWS_SENSE_DATA_LENGTH ); 535 ccb->csio.sense_len = TWS_SENSE_DATA_LENGTH; 536 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 537 } 538 ccb->csio.scsi_status = req->cmd_pkt->cmd.pkt_a.status; 539 540 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 541 mtx_lock(&sc->sim_lock); 542 xpt_done(ccb); 543 mtx_unlock(&sc->sim_lock); 544 545 callout_stop(&req->timeout); 546 tws_unmap_request(req->sc, req); 547 mtx_lock(&sc->q_lock); 548 tws_q_remove_request(sc, req, TWS_BUSY_Q); 549 tws_q_insert_tail(sc, req, TWS_FREE_Q); 550 mtx_unlock(&sc->q_lock); 551 } 552 553 static void 554 tws_passthru_err_complete(struct tws_request *req, 555 struct tws_command_header *hdr) 556 { 557 TWS_TRACE_DEBUG(req->sc, "entry", hdr, req->request_id); 558 req->error_code = hdr->status_block.error; 559 memcpy(&(req->cmd_pkt->hdr), hdr, sizeof(struct tws_command_header)); 560 tws_passthru_complete(req); 561 } 562 563 static void 564 tws_drain_busy_queue(struct tws_softc *sc) 565 { 566 struct tws_request *req; 567 union ccb *ccb; 568 TWS_TRACE_DEBUG(sc, "entry", 0, 0); 569 570 mtx_lock(&sc->q_lock); 571 req = tws_q_remove_tail(sc, TWS_BUSY_Q); 572 mtx_unlock(&sc->q_lock); 573 while ( req ) { 574 TWS_TRACE_DEBUG(sc, "moved to TWS_COMPLETE_Q", 0, req->request_id); 575 callout_stop(&req->timeout); 576 577 req->error_code = TWS_REQ_RET_RESET; 578 ccb = (union ccb *)(req->ccb_ptr); 579 580 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 581 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 582 ccb->ccb_h.status |= CAM_SCSI_BUS_RESET; 583 584 tws_unmap_request(req->sc, req); 585 586 mtx_lock(&sc->sim_lock); 587 xpt_done(req->ccb_ptr); 588 mtx_unlock(&sc->sim_lock); 589 590 mtx_lock(&sc->q_lock); 591 tws_q_insert_tail(sc, req, TWS_FREE_Q); 592 req = tws_q_remove_tail(sc, TWS_BUSY_Q); 593 mtx_unlock(&sc->q_lock); 594 } 595 } 596 597 static void 598 tws_drain_reserved_reqs(struct tws_softc *sc) 599 { 600 struct tws_request *r; 601 602 r = &sc->reqs[TWS_REQ_TYPE_AEN_FETCH]; 603 if ( r->state != TWS_REQ_STATE_FREE ) { 604 TWS_TRACE_DEBUG(sc, "reset aen req", 0, 0); 605 callout_stop(&r->timeout); 606 tws_unmap_request(sc, r); 607 free(r->data, M_TWS); 608 r->state = TWS_REQ_STATE_FREE; 609 r->error_code = TWS_REQ_RET_RESET; 610 } 611 612 r = &sc->reqs[TWS_REQ_TYPE_PASSTHRU]; 613 if ( r->state == TWS_REQ_STATE_BUSY ) { 614 TWS_TRACE_DEBUG(sc, "reset passthru req", 0, 0); 615 r->error_code = TWS_REQ_RET_RESET; 616 } 617 618 r = &sc->reqs[TWS_REQ_TYPE_GETSET_PARAM]; 619 if ( r->state != TWS_REQ_STATE_FREE ) { 620 TWS_TRACE_DEBUG(sc, "reset setparam req", 0, 0); 621 callout_stop(&r->timeout); 622 tws_unmap_request(sc, r); 623 free(r->data, M_TWS); 624 r->state = TWS_REQ_STATE_FREE; 625 r->error_code = TWS_REQ_RET_RESET; 626 } 627 } 628 629 static void 630 tws_drain_response_queue(struct tws_softc *sc) 631 { 632 u_int16_t req_id; 633 u_int64_t mfa; 634 while ( tws_get_response(sc, &req_id, &mfa) ); 635 } 636 637 static int32_t 638 tws_execute_scsi(struct tws_softc *sc, union ccb *ccb) 639 { 640 struct tws_command_packet *cmd_pkt; 641 struct tws_request *req; 642 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 643 struct ccb_scsiio *csio = &(ccb->csio); 644 int error; 645 u_int16_t lun; 646 647 mtx_assert(&sc->sim_lock, MA_OWNED); 648 if (ccb_h->target_id >= TWS_MAX_NUM_UNITS) { 649 TWS_TRACE_DEBUG(sc, "traget id too big", ccb_h->target_id, ccb_h->target_lun); 650 ccb_h->status |= CAM_TID_INVALID; 651 xpt_done(ccb); 652 return(0); 653 } 654 if (ccb_h->target_lun >= TWS_MAX_NUM_LUNS) { 655 TWS_TRACE_DEBUG(sc, "target lun 2 big", ccb_h->target_id, ccb_h->target_lun); 656 ccb_h->status |= CAM_LUN_INVALID; 657 xpt_done(ccb); 658 return(0); 659 } 660 661 if(ccb_h->flags & CAM_CDB_PHYS) { 662 TWS_TRACE_DEBUG(sc, "cdb phy", ccb_h->target_id, ccb_h->target_lun); 663 ccb_h->status = CAM_REQ_INVALID; 664 xpt_done(ccb); 665 return(0); 666 } 667 668 /* 669 * We are going to work on this request. Mark it as enqueued (though 670 * we don't actually queue it...) 671 */ 672 ccb_h->status |= CAM_SIM_QUEUED; 673 674 req = tws_get_request(sc, TWS_REQ_TYPE_SCSI_IO); 675 if ( !req ) { 676 TWS_TRACE_DEBUG(sc, "no reqs", ccb_h->target_id, ccb_h->target_lun); 677 ccb_h->status |= CAM_REQUEUE_REQ; 678 xpt_done(ccb); 679 return(0); 680 } 681 682 if((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 683 if(ccb_h->flags & CAM_DIR_IN) 684 req->flags |= TWS_DIR_IN; 685 if(ccb_h->flags & CAM_DIR_OUT) 686 req->flags |= TWS_DIR_OUT; 687 } else { 688 req->flags = TWS_DIR_NONE; /* no data */ 689 } 690 691 req->type = TWS_REQ_TYPE_SCSI_IO; 692 req->cb = tws_scsi_complete; 693 694 cmd_pkt = req->cmd_pkt; 695 /* cmd_pkt->hdr.header_desc.size_header = 128; */ 696 cmd_pkt->cmd.pkt_a.res__opcode = TWS_FW_CMD_EXECUTE_SCSI; 697 cmd_pkt->cmd.pkt_a.unit = ccb_h->target_id; 698 cmd_pkt->cmd.pkt_a.status = 0; 699 cmd_pkt->cmd.pkt_a.sgl_offset = 16; 700 701 /* lower nibble */ 702 lun = ccb_h->target_lun & 0XF; 703 lun = lun << 12; 704 cmd_pkt->cmd.pkt_a.lun_l4__req_id = lun | req->request_id; 705 /* upper nibble */ 706 lun = ccb_h->target_lun & 0XF0; 707 lun = lun << 8; 708 cmd_pkt->cmd.pkt_a.lun_h4__sgl_entries = lun; 709 710 #ifdef TWS_DEBUG 711 if ( csio->cdb_len > 16 ) 712 TWS_TRACE(sc, "cdb len too big", ccb_h->target_id, csio->cdb_len); 713 #endif 714 715 if(ccb_h->flags & CAM_CDB_POINTER) 716 bcopy(csio->cdb_io.cdb_ptr, cmd_pkt->cmd.pkt_a.cdb, csio->cdb_len); 717 else 718 bcopy(csio->cdb_io.cdb_bytes, cmd_pkt->cmd.pkt_a.cdb, csio->cdb_len); 719 720 req->data = ccb; 721 req->flags |= TWS_DATA_CCB; 722 /* save ccb ptr */ 723 req->ccb_ptr = ccb; 724 /* 725 * tws_map_load_data_callback will fill in the SGL, 726 * and submit the I/O. 727 */ 728 sc->stats.scsi_ios++; 729 callout_reset_sbt(&req->timeout, SBT_1MS * ccb->ccb_h.timeout, 0, 730 tws_timeout, req, 0); 731 error = tws_map_request(sc, req); 732 return(error); 733 } 734 735 int 736 tws_send_scsi_cmd(struct tws_softc *sc, int cmd) 737 { 738 struct tws_request *req; 739 struct tws_command_packet *cmd_pkt; 740 int error; 741 742 TWS_TRACE_DEBUG(sc, "entry",sc, cmd); 743 req = tws_get_request(sc, TWS_REQ_TYPE_AEN_FETCH); 744 745 if ( req == NULL ) 746 return(ENOMEM); 747 748 req->cb = tws_aen_complete; 749 750 cmd_pkt = req->cmd_pkt; 751 cmd_pkt->cmd.pkt_a.res__opcode = TWS_FW_CMD_EXECUTE_SCSI; 752 cmd_pkt->cmd.pkt_a.status = 0; 753 cmd_pkt->cmd.pkt_a.unit = 0; 754 cmd_pkt->cmd.pkt_a.sgl_offset = 16; 755 cmd_pkt->cmd.pkt_a.lun_l4__req_id = req->request_id; 756 757 cmd_pkt->cmd.pkt_a.cdb[0] = (u_int8_t)cmd; 758 cmd_pkt->cmd.pkt_a.cdb[4] = 128; 759 760 req->length = TWS_SECTOR_SIZE; 761 req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT); 762 if ( req->data == NULL ) 763 return(ENOMEM); 764 bzero(req->data, TWS_SECTOR_SIZE); 765 req->flags = TWS_DIR_IN; 766 767 callout_reset(&req->timeout, (TWS_IO_TIMEOUT * hz), tws_timeout, req); 768 error = tws_map_request(sc, req); 769 return(error); 770 771 } 772 773 int 774 tws_set_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 775 u_int32_t param_size, void *data) 776 { 777 struct tws_request *req; 778 struct tws_command_packet *cmd_pkt; 779 union tws_command_giga *cmd; 780 struct tws_getset_param *param; 781 int error; 782 783 req = tws_get_request(sc, TWS_REQ_TYPE_GETSET_PARAM); 784 if ( req == NULL ) { 785 TWS_TRACE_DEBUG(sc, "null req", 0, 0); 786 return(ENOMEM); 787 } 788 789 req->length = TWS_SECTOR_SIZE; 790 req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT); 791 if ( req->data == NULL ) 792 return(ENOMEM); 793 bzero(req->data, TWS_SECTOR_SIZE); 794 param = (struct tws_getset_param *)req->data; 795 796 req->cb = tws_getset_param_complete; 797 req->flags = TWS_DIR_OUT; 798 cmd_pkt = req->cmd_pkt; 799 800 cmd = &cmd_pkt->cmd.pkt_g; 801 cmd->param.sgl_off__opcode = 802 BUILD_SGL_OFF__OPCODE(2, TWS_FW_CMD_SET_PARAM); 803 cmd->param.request_id = (u_int8_t)req->request_id; 804 cmd->param.host_id__unit = 0; 805 cmd->param.param_count = 1; 806 cmd->param.size = 2; /* map routine will add sgls */ 807 808 /* Specify which parameter we want to set. */ 809 param->table_id = (table_id | TWS_9K_PARAM_DESCRIPTOR); 810 param->parameter_id = (u_int8_t)(param_id); 811 param->parameter_size_bytes = (u_int16_t)param_size; 812 memcpy(param->data, data, param_size); 813 814 callout_reset(&req->timeout, (TWS_IOCTL_TIMEOUT * hz), tws_timeout, req); 815 error = tws_map_request(sc, req); 816 return(error); 817 818 } 819 820 int 821 tws_get_param(struct tws_softc *sc, u_int32_t table_id, u_int32_t param_id, 822 u_int32_t param_size, void *data) 823 { 824 struct tws_request *req; 825 struct tws_command_packet *cmd_pkt; 826 union tws_command_giga *cmd; 827 struct tws_getset_param *param; 828 u_int16_t reqid; 829 u_int64_t mfa; 830 int error = SUCCESS; 831 832 req = tws_get_request(sc, TWS_REQ_TYPE_GETSET_PARAM); 833 if ( req == NULL ) { 834 TWS_TRACE_DEBUG(sc, "null req", 0, 0); 835 return(FAILURE); 836 } 837 838 req->length = TWS_SECTOR_SIZE; 839 req->data = malloc(TWS_SECTOR_SIZE, M_TWS, M_NOWAIT); 840 if ( req->data == NULL ) 841 return(FAILURE); 842 bzero(req->data, TWS_SECTOR_SIZE); 843 param = (struct tws_getset_param *)req->data; 844 845 req->cb = NULL; 846 req->flags = TWS_DIR_IN; 847 cmd_pkt = req->cmd_pkt; 848 849 cmd = &cmd_pkt->cmd.pkt_g; 850 cmd->param.sgl_off__opcode = 851 BUILD_SGL_OFF__OPCODE(2, TWS_FW_CMD_GET_PARAM); 852 cmd->param.request_id = (u_int8_t)req->request_id; 853 cmd->param.host_id__unit = 0; 854 cmd->param.param_count = 1; 855 cmd->param.size = 2; /* map routine will add sgls */ 856 857 /* Specify which parameter we want to set. */ 858 param->table_id = (table_id | TWS_9K_PARAM_DESCRIPTOR); 859 param->parameter_id = (u_int8_t)(param_id); 860 param->parameter_size_bytes = (u_int16_t)param_size; 861 862 error = tws_map_request(sc, req); 863 if (!error) { 864 reqid = tws_poll4_response(sc, &mfa); 865 tws_unmap_request(sc, req); 866 867 if ( reqid == TWS_REQ_TYPE_GETSET_PARAM ) { 868 memcpy(data, param->data, param_size); 869 } else { 870 error = FAILURE; 871 } 872 } 873 874 free(req->data, M_TWS); 875 req->state = TWS_REQ_STATE_FREE; 876 return(error); 877 878 } 879 880 void 881 tws_unmap_request(struct tws_softc *sc, struct tws_request *req) 882 { 883 if (req->data != NULL) { 884 if ( req->flags & TWS_DIR_IN ) 885 bus_dmamap_sync(sc->data_tag, req->dma_map, 886 BUS_DMASYNC_POSTREAD); 887 if ( req->flags & TWS_DIR_OUT ) 888 bus_dmamap_sync(sc->data_tag, req->dma_map, 889 BUS_DMASYNC_POSTWRITE); 890 mtx_lock(&sc->io_lock); 891 bus_dmamap_unload(sc->data_tag, req->dma_map); 892 mtx_unlock(&sc->io_lock); 893 } 894 } 895 896 int32_t 897 tws_map_request(struct tws_softc *sc, struct tws_request *req) 898 { 899 int32_t error = 0; 900 901 /* If the command involves data, map that too. */ 902 if (req->data != NULL) { 903 int my_flags = ((req->type == TWS_REQ_TYPE_SCSI_IO) ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT); 904 905 /* 906 * Map the data buffer into bus space and build the SG list. 907 */ 908 mtx_lock(&sc->io_lock); 909 if (req->flags & TWS_DATA_CCB) 910 error = bus_dmamap_load_ccb(sc->data_tag, req->dma_map, 911 req->data, 912 tws_dmamap_data_load_cbfn, req, 913 my_flags); 914 else 915 error = bus_dmamap_load(sc->data_tag, req->dma_map, 916 req->data, req->length, 917 tws_dmamap_data_load_cbfn, req, 918 my_flags); 919 mtx_unlock(&sc->io_lock); 920 921 if (error == EINPROGRESS) { 922 TWS_TRACE(sc, "in progress", 0, error); 923 tws_freeze_simq(sc, req); 924 error = 0; // EINPROGRESS is not a fatal error. 925 } 926 } else { /* no data involved */ 927 error = tws_submit_command(sc, req); 928 } 929 return(error); 930 } 931 932 static void 933 tws_dmamap_data_load_cbfn(void *arg, bus_dma_segment_t *segs, 934 int nseg, int error) 935 { 936 struct tws_request *req = (struct tws_request *)arg; 937 struct tws_softc *sc = req->sc; 938 u_int16_t sgls = nseg; 939 void *sgl_ptr; 940 struct tws_cmd_generic *gcmd; 941 942 if ( error ) { 943 TWS_TRACE(sc, "SOMETHING BAD HAPPENED! error = %d\n", error, 0); 944 } 945 946 if ( error == EFBIG ) { 947 TWS_TRACE(sc, "not enough data segs", 0, nseg); 948 req->error_code = error; 949 req->ccb_ptr->ccb_h.status = CAM_REQ_TOO_BIG; 950 return; 951 } 952 953 if ( req->flags & TWS_DIR_IN ) 954 bus_dmamap_sync(req->sc->data_tag, req->dma_map, 955 BUS_DMASYNC_PREREAD); 956 if ( req->flags & TWS_DIR_OUT ) 957 bus_dmamap_sync(req->sc->data_tag, req->dma_map, 958 BUS_DMASYNC_PREWRITE); 959 if ( segs ) { 960 if ( (req->type == TWS_REQ_TYPE_PASSTHRU && 961 GET_OPCODE(req->cmd_pkt->cmd.pkt_a.res__opcode) != 962 TWS_FW_CMD_EXECUTE_SCSI) || 963 req->type == TWS_REQ_TYPE_GETSET_PARAM) { 964 gcmd = &req->cmd_pkt->cmd.pkt_g.generic; 965 sgl_ptr = (u_int32_t *)(gcmd) + gcmd->size; 966 gcmd->size += sgls * 967 ((req->sc->is64bit && !tws_use_32bit_sgls) ? 4 : 2 ); 968 tws_fill_sg_list(req->sc, (void *)segs, sgl_ptr, sgls); 969 970 } else { 971 tws_fill_sg_list(req->sc, (void *)segs, 972 (void *)&(req->cmd_pkt->cmd.pkt_a.sg_list), sgls); 973 req->cmd_pkt->cmd.pkt_a.lun_h4__sgl_entries |= sgls ; 974 } 975 } 976 977 req->error_code = tws_submit_command(req->sc, req); 978 979 } 980 981 static void 982 tws_fill_sg_list(struct tws_softc *sc, void *sgl_src, void *sgl_dest, 983 u_int16_t num_sgl_entries) 984 { 985 int i; 986 987 if ( sc->is64bit ) { 988 struct tws_sg_desc64 *sgl_s = (struct tws_sg_desc64 *)sgl_src; 989 990 if ( !tws_use_32bit_sgls ) { 991 struct tws_sg_desc64 *sgl_d = (struct tws_sg_desc64 *)sgl_dest; 992 if ( num_sgl_entries > TWS_MAX_64BIT_SG_ELEMENTS ) 993 TWS_TRACE(sc, "64bit sg overflow", num_sgl_entries, 0); 994 for (i = 0; i < num_sgl_entries; i++) { 995 sgl_d[i].address = sgl_s->address; 996 sgl_d[i].length = sgl_s->length; 997 sgl_d[i].flag = 0; 998 sgl_d[i].reserved = 0; 999 sgl_s = (struct tws_sg_desc64 *) (((u_int8_t *)sgl_s) + 1000 sizeof(bus_dma_segment_t)); 1001 } 1002 } else { 1003 struct tws_sg_desc32 *sgl_d = (struct tws_sg_desc32 *)sgl_dest; 1004 if ( num_sgl_entries > TWS_MAX_32BIT_SG_ELEMENTS ) 1005 TWS_TRACE(sc, "32bit sg overflow", num_sgl_entries, 0); 1006 for (i = 0; i < num_sgl_entries; i++) { 1007 sgl_d[i].address = sgl_s->address; 1008 sgl_d[i].length = sgl_s->length; 1009 sgl_d[i].flag = 0; 1010 sgl_s = (struct tws_sg_desc64 *) (((u_int8_t *)sgl_s) + 1011 sizeof(bus_dma_segment_t)); 1012 } 1013 } 1014 } else { 1015 struct tws_sg_desc32 *sgl_s = (struct tws_sg_desc32 *)sgl_src; 1016 struct tws_sg_desc32 *sgl_d = (struct tws_sg_desc32 *)sgl_dest; 1017 1018 if ( num_sgl_entries > TWS_MAX_32BIT_SG_ELEMENTS ) 1019 TWS_TRACE(sc, "32bit sg overflow", num_sgl_entries, 0); 1020 1021 for (i = 0; i < num_sgl_entries; i++) { 1022 sgl_d[i].address = sgl_s[i].address; 1023 sgl_d[i].length = sgl_s[i].length; 1024 sgl_d[i].flag = 0; 1025 } 1026 } 1027 } 1028 1029 void 1030 tws_intr(void *arg) 1031 { 1032 struct tws_softc *sc = (struct tws_softc *)arg; 1033 u_int32_t histat=0, db=0; 1034 1035 if (!(sc)) { 1036 device_printf(sc->tws_dev, "null softc!!!\n"); 1037 return; 1038 } 1039 1040 if ( tws_get_state(sc) == TWS_RESET ) { 1041 return; 1042 } 1043 1044 if ( tws_get_state(sc) != TWS_ONLINE ) { 1045 return; 1046 } 1047 1048 sc->stats.num_intrs++; 1049 histat = tws_read_reg(sc, TWS_I2O0_HISTAT, 4); 1050 if ( histat & TWS_BIT2 ) { 1051 TWS_TRACE_DEBUG(sc, "door bell :)", histat, TWS_I2O0_HISTAT); 1052 db = tws_read_reg(sc, TWS_I2O0_IOBDB, 4); 1053 if ( db & TWS_BIT21 ) { 1054 tws_intr_attn_error(sc); 1055 return; 1056 } 1057 if ( db & TWS_BIT18 ) { 1058 tws_intr_attn_aen(sc); 1059 } 1060 } 1061 1062 if ( histat & TWS_BIT3 ) { 1063 tws_intr_resp(sc); 1064 } 1065 } 1066 1067 static void 1068 tws_intr_attn_aen(struct tws_softc *sc) 1069 { 1070 1071 /* maskoff db intrs until all the aens are fetched */ 1072 /* tws_disable_db_intr(sc); */ 1073 tws_fetch_aen((void *)sc); 1074 tws_write_reg(sc, TWS_I2O0_HOBDBC, TWS_BIT18, 4); 1075 (void)tws_read_reg(sc, TWS_I2O0_IOBDB, 4); 1076 1077 } 1078 1079 static void 1080 tws_intr_attn_error(struct tws_softc *sc) 1081 { 1082 1083 TWS_TRACE(sc, "attn error", 0, 0); 1084 tws_write_reg(sc, TWS_I2O0_HOBDBC, ~0, 4); 1085 (void)tws_read_reg(sc, TWS_I2O0_IOBDB, 4); 1086 device_printf(sc->tws_dev, "Micro controller error.\n"); 1087 tws_reset(sc); 1088 } 1089 1090 static void 1091 tws_intr_resp(struct tws_softc *sc) 1092 { 1093 u_int16_t req_id; 1094 u_int64_t mfa; 1095 1096 while ( tws_get_response(sc, &req_id, &mfa) ) { 1097 sc->stats.reqs_out++; 1098 if ( req_id == TWS_INVALID_REQID ) { 1099 TWS_TRACE_DEBUG(sc, "invalid req_id", mfa, req_id); 1100 sc->stats.reqs_errored++; 1101 tws_err_complete(sc, mfa); 1102 continue; 1103 } 1104 sc->reqs[req_id].cb(&sc->reqs[req_id]); 1105 } 1106 1107 } 1108 1109 static void 1110 tws_poll(struct cam_sim *sim) 1111 { 1112 struct tws_softc *sc = (struct tws_softc *)cam_sim_softc(sim); 1113 TWS_TRACE_DEBUG(sc, "entry", 0, 0); 1114 tws_intr((void *) sc); 1115 } 1116 1117 void 1118 tws_timeout(void *arg) 1119 { 1120 struct tws_request *req = (struct tws_request *)arg; 1121 struct tws_softc *sc = req->sc; 1122 1123 if ( req->error_code == TWS_REQ_RET_RESET ) { 1124 return; 1125 } 1126 1127 mtx_lock(&sc->gen_lock); 1128 if ( req->error_code == TWS_REQ_RET_RESET ) { 1129 mtx_unlock(&sc->gen_lock); 1130 return; 1131 } 1132 1133 if ( tws_get_state(sc) == TWS_RESET ) { 1134 mtx_unlock(&sc->gen_lock); 1135 return; 1136 } 1137 1138 xpt_freeze_simq(sc->sim, 1); 1139 1140 tws_send_event(sc, TWS_RESET_START); 1141 1142 if (req->type == TWS_REQ_TYPE_SCSI_IO) { 1143 device_printf(sc->tws_dev, "I/O Request timed out... Resetting controller\n"); 1144 } else if (req->type == TWS_REQ_TYPE_PASSTHRU) { 1145 device_printf(sc->tws_dev, "IOCTL Request timed out... Resetting controller\n"); 1146 } else { 1147 device_printf(sc->tws_dev, "Internal Request timed out... Resetting controller\n"); 1148 } 1149 1150 tws_assert_soft_reset(sc); 1151 tws_turn_off_interrupts(sc); 1152 tws_reset_cb( (void*) sc ); 1153 tws_reinit( (void*) sc ); 1154 1155 // device_printf(sc->tws_dev, "Controller Reset complete!\n"); 1156 tws_send_event(sc, TWS_RESET_COMPLETE); 1157 mtx_unlock(&sc->gen_lock); 1158 1159 xpt_release_simq(sc->sim, 1); 1160 } 1161 1162 void 1163 tws_reset(void *arg) 1164 { 1165 struct tws_softc *sc = (struct tws_softc *)arg; 1166 1167 mtx_lock(&sc->gen_lock); 1168 if ( tws_get_state(sc) == TWS_RESET ) { 1169 mtx_unlock(&sc->gen_lock); 1170 return; 1171 } 1172 1173 xpt_freeze_simq(sc->sim, 1); 1174 1175 tws_send_event(sc, TWS_RESET_START); 1176 1177 device_printf(sc->tws_dev, "Resetting controller\n"); 1178 1179 tws_assert_soft_reset(sc); 1180 tws_turn_off_interrupts(sc); 1181 tws_reset_cb( (void*) sc ); 1182 tws_reinit( (void*) sc ); 1183 1184 // device_printf(sc->tws_dev, "Controller Reset complete!\n"); 1185 tws_send_event(sc, TWS_RESET_COMPLETE); 1186 mtx_unlock(&sc->gen_lock); 1187 1188 xpt_release_simq(sc->sim, 1); 1189 } 1190 1191 static void 1192 tws_reset_cb(void *arg) 1193 { 1194 struct tws_softc *sc = (struct tws_softc *)arg; 1195 time_t endt; 1196 int found = 0; 1197 u_int32_t reg; 1198 1199 if ( tws_get_state(sc) != TWS_RESET ) { 1200 return; 1201 } 1202 1203 // device_printf(sc->tws_dev, "Draining Busy Queue\n"); 1204 tws_drain_busy_queue(sc); 1205 // device_printf(sc->tws_dev, "Draining Reserved Reqs\n"); 1206 tws_drain_reserved_reqs(sc); 1207 // device_printf(sc->tws_dev, "Draining Response Queue\n"); 1208 tws_drain_response_queue(sc); 1209 1210 // device_printf(sc->tws_dev, "Looking for controller ready flag...\n"); 1211 endt = TWS_LOCAL_TIME + TWS_POLL_TIMEOUT; 1212 while ((TWS_LOCAL_TIME <= endt) && (!found)) { 1213 reg = tws_read_reg(sc, TWS_I2O0_SCRPD3, 4); 1214 if ( reg & TWS_BIT13 ) { 1215 found = 1; 1216 // device_printf(sc->tws_dev, " ... Got it!\n"); 1217 } 1218 } 1219 if ( !found ) 1220 device_printf(sc->tws_dev, " ... Controller ready flag NOT found!\n"); 1221 } 1222 1223 static void 1224 tws_reinit(void *arg) 1225 { 1226 struct tws_softc *sc = (struct tws_softc *)arg; 1227 int timeout_val=0; 1228 int try=2; 1229 int done=0; 1230 1231 // device_printf(sc->tws_dev, "Waiting for Controller Ready\n"); 1232 while ( !done && try ) { 1233 if ( tws_ctlr_ready(sc) ) { 1234 done = 1; 1235 break; 1236 } else { 1237 timeout_val += 5; 1238 if ( timeout_val >= TWS_RESET_TIMEOUT ) { 1239 timeout_val = 0; 1240 if ( try ) 1241 tws_assert_soft_reset(sc); 1242 try--; 1243 } 1244 mtx_sleep(sc, &sc->gen_lock, 0, "tws_reinit", 5*hz); 1245 } 1246 } 1247 1248 if (!done) { 1249 device_printf(sc->tws_dev, "FAILED to get Controller Ready!\n"); 1250 return; 1251 } 1252 1253 sc->obfl_q_overrun = false; 1254 // device_printf(sc->tws_dev, "Sending initConnect\n"); 1255 if ( tws_init_connect(sc, tws_queue_depth) ) { 1256 TWS_TRACE_DEBUG(sc, "initConnect failed", 0, sc->is64bit); 1257 } 1258 tws_init_obfl_q(sc); 1259 1260 tws_turn_on_interrupts(sc); 1261 1262 wakeup_one(sc); 1263 } 1264 1265 static void 1266 tws_freeze_simq(struct tws_softc *sc, struct tws_request *req) 1267 { 1268 /* Only for IO commands */ 1269 if (req->type == TWS_REQ_TYPE_SCSI_IO) { 1270 union ccb *ccb = (union ccb *)(req->ccb_ptr); 1271 1272 xpt_freeze_simq(sc->sim, 1); 1273 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1274 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 1275 } 1276 } 1277 1278 TUNABLE_INT("hw.tws.cam_depth", &tws_cam_depth); 1279