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