xref: /freebsd/sys/dev/tws/tws_cam.c (revision ab40f58ccfe6c07ebefddc72f4661a52fe746353)
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 
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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