1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
5 * Copyright (c) 2004-05 Vinod Kashyap.
6 * All rights reserved.
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
30 /*
31 * AMCC'S 3ware driver for 9000 series storage controllers.
32 *
33 * Author: Vinod Kashyap
34 * Modifications by: Adam Radford
35 * Modifications by: Manjunath Ranganathaiah
36 */
37
38 /*
39 * FreeBSD CAM related functions.
40 */
41
42 #include <dev/twa/tw_osl_includes.h>
43
44 #include <cam/cam.h>
45 #include <cam/cam_ccb.h>
46 #include <cam/cam_sim.h>
47 #include <cam/cam_xpt_sim.h>
48 #include <cam/cam_debug.h>
49 #include <cam/cam_periph.h>
50
51 #include <cam/scsi/scsi_all.h>
52 #include <cam/scsi/scsi_message.h>
53
54 static TW_VOID twa_action(struct cam_sim *sim, union ccb *ccb);
55 static TW_VOID twa_poll(struct cam_sim *sim);
56
57 static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req,
58 union ccb *ccb);
59
60 /*
61 * Function name: tw_osli_cam_attach
62 * Description: Attaches the driver to CAM.
63 *
64 * Input: sc -- ptr to OSL internal ctlr context
65 * Output: None
66 * Return value: 0 -- success
67 * non-zero-- failure
68 */
69 TW_INT32
tw_osli_cam_attach(struct twa_softc * sc)70 tw_osli_cam_attach(struct twa_softc *sc)
71 {
72 struct cam_devq *devq;
73
74 tw_osli_dbg_dprintf(3, sc, "entered");
75
76 /*
77 * Create the device queue for our SIM.
78 */
79 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) {
80 tw_osli_printf(sc, "error = %d",
81 TW_CL_SEVERITY_ERROR_STRING,
82 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
83 0x2100,
84 "Failed to create SIM device queue",
85 ENOMEM);
86 return(ENOMEM);
87 }
88
89 /*
90 * Create a SIM entry. Though we can support TW_OSLI_MAX_NUM_REQUESTS
91 * simultaneous requests, we claim to be able to handle only
92 * TW_OSLI_MAX_NUM_IOS (two less), so that we always have a request
93 * packet available to service ioctls and AENs.
94 */
95 tw_osli_dbg_dprintf(3, sc, "Calling cam_sim_alloc");
96 sc->sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc,
97 device_get_unit(sc->bus_dev), sc->sim_lock,
98 TW_OSLI_MAX_NUM_IOS, 1, devq);
99 if (sc->sim == NULL) {
100 cam_simq_free(devq);
101 tw_osli_printf(sc, "error = %d",
102 TW_CL_SEVERITY_ERROR_STRING,
103 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
104 0x2101,
105 "Failed to create a SIM entry",
106 ENOMEM);
107 return(ENOMEM);
108 }
109
110 /*
111 * Register the bus.
112 */
113 tw_osli_dbg_dprintf(3, sc, "Calling xpt_bus_register");
114 mtx_lock(sc->sim_lock);
115 if (xpt_bus_register(sc->sim, sc->bus_dev, 0) != CAM_SUCCESS) {
116 cam_sim_free(sc->sim, TRUE);
117 sc->sim = NULL; /* so cam_detach will not try to free it */
118 tw_osli_printf(sc, "error = %d",
119 TW_CL_SEVERITY_ERROR_STRING,
120 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
121 0x2102,
122 "Failed to register the bus",
123 ENXIO);
124 mtx_unlock(sc->sim_lock);
125 return(ENXIO);
126 }
127
128 tw_osli_dbg_dprintf(3, sc, "Calling xpt_create_path");
129 if (xpt_create_path(&sc->path, NULL,
130 cam_sim_path(sc->sim),
131 CAM_TARGET_WILDCARD,
132 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
133 xpt_bus_deregister(cam_sim_path (sc->sim));
134 /* Passing TRUE to cam_sim_free will free the devq as well. */
135 cam_sim_free(sc->sim, TRUE);
136 tw_osli_printf(sc, "error = %d",
137 TW_CL_SEVERITY_ERROR_STRING,
138 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
139 0x2103,
140 "Failed to create path",
141 ENXIO);
142 mtx_unlock(sc->sim_lock);
143 return(ENXIO);
144 }
145 mtx_unlock(sc->sim_lock);
146
147 tw_osli_dbg_dprintf(3, sc, "exiting");
148 return(0);
149 }
150
151 /*
152 * Function name: tw_osli_cam_detach
153 * Description: Detaches the driver from CAM.
154 *
155 * Input: sc -- ptr to OSL internal ctlr context
156 * Output: None
157 * Return value: None
158 */
159 TW_VOID
tw_osli_cam_detach(struct twa_softc * sc)160 tw_osli_cam_detach(struct twa_softc *sc)
161 {
162 tw_osli_dbg_dprintf(3, sc, "entered");
163
164 mtx_lock(sc->sim_lock);
165
166 if (sc->path)
167 xpt_free_path(sc->path);
168 if (sc->sim) {
169 xpt_bus_deregister(cam_sim_path(sc->sim));
170 /* Passing TRUE to cam_sim_free will free the devq as well. */
171 cam_sim_free(sc->sim, TRUE);
172 }
173 /* It's ok have 1 hold count while destroying the mutex */
174 mtx_destroy(sc->sim_lock);
175 }
176
177 /*
178 * Function name: tw_osli_execute_scsi
179 * Description: Build a fw cmd, based on a CAM style ccb, and
180 * send it down.
181 *
182 * Input: req -- ptr to OSL internal request context
183 * ccb -- ptr to CAM style ccb
184 * Output: None
185 * Return value: 0 -- success
186 * non-zero-- failure
187 */
188 TW_INT32
tw_osli_execute_scsi(struct tw_osli_req_context * req,union ccb * ccb)189 tw_osli_execute_scsi(struct tw_osli_req_context *req, union ccb *ccb)
190 {
191 struct twa_softc *sc = req->ctlr;
192 struct tw_cl_req_packet *req_pkt;
193 struct tw_cl_scsi_req_packet *scsi_req;
194 struct ccb_hdr *ccb_h = &(ccb->ccb_h);
195 struct ccb_scsiio *csio = &(ccb->csio);
196 TW_INT32 error;
197
198 tw_osli_dbg_dprintf(10, sc, "SCSI I/O request 0x%x",
199 csio->cdb_io.cdb_bytes[0]);
200
201 if (ccb_h->target_id >= TW_CL_MAX_NUM_UNITS) {
202 tw_osli_dbg_dprintf(3, sc, "Invalid target. PTL = %x %x %jx",
203 ccb_h->path_id, ccb_h->target_id,
204 (uintmax_t)ccb_h->target_lun);
205 ccb_h->status |= CAM_TID_INVALID;
206 xpt_done(ccb);
207 return(1);
208 }
209 if (ccb_h->target_lun >= TW_CL_MAX_NUM_LUNS) {
210 tw_osli_dbg_dprintf(3, sc, "Invalid lun. PTL = %x %x %jx",
211 ccb_h->path_id, ccb_h->target_id,
212 (uintmax_t)ccb_h->target_lun);
213 ccb_h->status |= CAM_LUN_INVALID;
214 xpt_done(ccb);
215 return(1);
216 }
217
218 if(ccb_h->flags & CAM_CDB_PHYS) {
219 tw_osli_printf(sc, "",
220 TW_CL_SEVERITY_ERROR_STRING,
221 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
222 0x2105,
223 "Physical CDB address!");
224 ccb_h->status = CAM_REQ_INVALID;
225 xpt_done(ccb);
226 return(1);
227 }
228
229 /*
230 * We are going to work on this request. Mark it as enqueued (though
231 * we don't actually queue it...)
232 */
233 ccb_h->status |= CAM_SIM_QUEUED;
234
235 if((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
236 if(ccb_h->flags & CAM_DIR_IN)
237 req->flags |= TW_OSLI_REQ_FLAGS_DATA_IN;
238 else
239 req->flags |= TW_OSLI_REQ_FLAGS_DATA_OUT;
240 }
241
242 /* Build the CL understood request packet for SCSI cmds. */
243 req_pkt = &req->req_pkt;
244 req_pkt->status = 0;
245 req_pkt->tw_osl_callback = tw_osl_complete_io;
246 scsi_req = &(req_pkt->gen_req_pkt.scsi_req);
247 scsi_req->unit = ccb_h->target_id;
248 scsi_req->lun = ccb_h->target_lun;
249 scsi_req->sense_len = 0;
250 scsi_req->sense_data = (TW_UINT8 *)(&csio->sense_data);
251 scsi_req->scsi_status = 0;
252 if(ccb_h->flags & CAM_CDB_POINTER)
253 scsi_req->cdb = csio->cdb_io.cdb_ptr;
254 else
255 scsi_req->cdb = csio->cdb_io.cdb_bytes;
256 scsi_req->cdb_len = csio->cdb_len;
257
258 if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) {
259 tw_osli_printf(sc, "size = %d",
260 TW_CL_SEVERITY_ERROR_STRING,
261 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
262 0x2106,
263 "I/O size too big",
264 csio->dxfer_len);
265 ccb_h->status = CAM_REQ_TOO_BIG;
266 ccb_h->status &= ~CAM_SIM_QUEUED;
267 xpt_done(ccb);
268 return(1);
269 }
270 if ((ccb_h->flags & CAM_DATA_MASK) == CAM_DATA_VADDR) {
271 if ((req->length = csio->dxfer_len) != 0) {
272 req->data = csio->data_ptr;
273 scsi_req->sgl_entries = 1;
274 }
275 } else
276 req->flags |= TW_OSLI_REQ_FLAGS_CCB;
277 req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000);
278
279 /*
280 * twa_map_load_data_callback will fill in the SGL,
281 * and submit the I/O.
282 */
283 error = tw_osli_map_request(req);
284 if ((error) && (req->flags & TW_OSLI_REQ_FLAGS_FAILED)) {
285 req->deadline = 0;
286 ccb_h->status = CAM_REQ_CMP_ERR;
287 ccb_h->status &= ~CAM_SIM_QUEUED;
288 xpt_done(ccb);
289 }
290 return(error);
291 }
292
293 /*
294 * Function name: twa_action
295 * Description: Driver entry point for CAM's use.
296 *
297 * Input: sim -- sim corresponding to the ctlr
298 * ccb -- ptr to CAM request
299 * Output: None
300 * Return value: None
301 */
302 TW_VOID
twa_action(struct cam_sim * sim,union ccb * ccb)303 twa_action(struct cam_sim *sim, union ccb *ccb)
304 {
305 struct twa_softc *sc = (struct twa_softc *)cam_sim_softc(sim);
306 struct ccb_hdr *ccb_h = &(ccb->ccb_h);
307
308 switch (ccb_h->func_code) {
309 case XPT_SCSI_IO: /* SCSI I/O */
310 {
311 struct tw_osli_req_context *req;
312
313 req = tw_osli_get_request(sc);
314 if (req == NULL) {
315 tw_osli_dbg_dprintf(2, sc, "Cannot get request pkt.");
316 /*
317 * Freeze the simq to maintain ccb ordering. The next
318 * ccb that gets completed will unfreeze the simq.
319 */
320 ccb_h->status &= ~CAM_SIM_QUEUED;
321 ccb_h->status |= CAM_REQUEUE_REQ;
322 xpt_done(ccb);
323 break;
324 }
325
326 if ((tw_cl_is_reset_needed(&(req->ctlr->ctlr_handle)))) {
327 ccb_h->status &= ~CAM_SIM_QUEUED;
328 ccb_h->status |= CAM_REQUEUE_REQ;
329 xpt_done(ccb);
330 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
331 break;
332 }
333
334 req->req_handle.osl_req_ctxt = req;
335 req->req_handle.is_io = TW_CL_TRUE;
336 req->orig_req = ccb;
337 if (tw_osli_execute_scsi(req, ccb))
338 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
339 break;
340 }
341
342 case XPT_ABORT:
343 tw_osli_dbg_dprintf(2, sc, "Abort request.");
344 ccb_h->status = CAM_UA_ABORT;
345 xpt_done(ccb);
346 break;
347
348 case XPT_RESET_BUS:
349 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_FALSE,
350 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
351 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
352 "Received Reset Bus request from CAM",
353 " ");
354
355 tw_cl_set_reset_needed(&(sc->ctlr_handle));
356 ccb_h->status = CAM_REQ_CMP;
357 xpt_done(ccb);
358 break;
359
360 case XPT_SET_TRAN_SETTINGS:
361 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS");
362
363 /*
364 * This command is not supported, since it's very specific
365 * to SCSI, and we are doing ATA.
366 */
367 ccb_h->status = CAM_FUNC_NOTAVAIL;
368 xpt_done(ccb);
369 break;
370
371 case XPT_GET_TRAN_SETTINGS:
372 {
373 struct ccb_trans_settings *cts = &ccb->cts;
374 struct ccb_trans_settings_scsi *scsi =
375 &cts->proto_specific.scsi;
376 struct ccb_trans_settings_spi *spi =
377 &cts->xport_specific.spi;
378
379 cts->protocol = PROTO_SCSI;
380 cts->protocol_version = SCSI_REV_2;
381 cts->transport = XPORT_SPI;
382 cts->transport_version = 2;
383
384 spi->valid = CTS_SPI_VALID_DISC;
385 spi->flags = CTS_SPI_FLAGS_DISC_ENB;
386 scsi->valid = CTS_SCSI_VALID_TQ;
387 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
388 tw_osli_dbg_dprintf(3, sc, "XPT_GET_TRAN_SETTINGS");
389 ccb_h->status = CAM_REQ_CMP;
390 xpt_done(ccb);
391 break;
392 }
393
394 case XPT_CALC_GEOMETRY:
395 tw_osli_dbg_dprintf(3, sc, "XPT_CALC_GEOMETRY");
396 cam_calc_geometry(&ccb->ccg, 1/* extended */);
397 xpt_done(ccb);
398 break;
399
400 case XPT_PATH_INQ: /* Path inquiry -- get twa properties */
401 {
402 struct ccb_pathinq *path_inq = &ccb->cpi;
403
404 tw_osli_dbg_dprintf(3, sc, "XPT_PATH_INQ request");
405
406 path_inq->version_num = 1;
407 path_inq->hba_inquiry = 0;
408 path_inq->target_sprt = 0;
409 path_inq->hba_misc = 0;
410 path_inq->hba_eng_cnt = 0;
411 path_inq->max_target = TW_CL_MAX_NUM_UNITS;
412 path_inq->max_lun = TW_CL_MAX_NUM_LUNS - 1;
413 path_inq->unit_number = cam_sim_unit(sim);
414 path_inq->bus_id = cam_sim_bus(sim);
415 path_inq->initiator_id = TW_CL_MAX_NUM_UNITS;
416 path_inq->base_transfer_speed = 100000;
417 strlcpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN);
418 strlcpy(path_inq->hba_vid, "3ware", HBA_IDLEN);
419 strlcpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN);
420 path_inq->transport = XPORT_SPI;
421 path_inq->transport_version = 2;
422 path_inq->protocol = PROTO_SCSI;
423 path_inq->protocol_version = SCSI_REV_2;
424 path_inq->maxio = TW_CL_MAX_IO_SIZE;
425 ccb_h->status = CAM_REQ_CMP;
426 xpt_done(ccb);
427 break;
428 }
429
430 default:
431 tw_osli_dbg_dprintf(3, sc, "func_code = %x", ccb_h->func_code);
432 ccb_h->status = CAM_REQ_INVALID;
433 xpt_done(ccb);
434 break;
435 }
436 }
437
438 /*
439 * Function name: twa_poll
440 * Description: Driver entry point called when interrupts are not
441 * available.
442 *
443 * Input: sim -- sim corresponding to the controller
444 * Output: None
445 * Return value: None
446 */
447 TW_VOID
twa_poll(struct cam_sim * sim)448 twa_poll(struct cam_sim *sim)
449 {
450 struct twa_softc *sc = (struct twa_softc *)(cam_sim_softc(sim));
451
452 tw_osli_dbg_dprintf(3, sc, "entering; sc = %p", sc);
453 tw_cl_interrupt(&(sc->ctlr_handle));
454 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc);
455 }
456
457 /*
458 * Function name: tw_osli_request_bus_scan
459 * Description: Requests CAM for a scan of the bus.
460 *
461 * Input: sc -- ptr to per ctlr structure
462 * Output: None
463 * Return value: 0 -- success
464 * non-zero-- failure
465 */
466 TW_INT32
tw_osli_request_bus_scan(struct twa_softc * sc)467 tw_osli_request_bus_scan(struct twa_softc *sc)
468 {
469 union ccb *ccb;
470
471 tw_osli_dbg_dprintf(3, sc, "entering");
472
473 /* If we get here before sc->sim is initialized, return an error. */
474 if (!(sc->sim))
475 return(ENXIO);
476 if ((ccb = xpt_alloc_ccb()) == NULL)
477 return(ENOMEM);
478 mtx_lock(sc->sim_lock);
479 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim),
480 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
481 xpt_free_ccb(ccb);
482 mtx_unlock(sc->sim_lock);
483 return(EIO);
484 }
485
486 xpt_rescan(ccb);
487 mtx_unlock(sc->sim_lock);
488 return(0);
489 }
490
491 /*
492 * Function name: tw_osli_disallow_new_requests
493 * Description: Calls the appropriate CAM function, so as to freeze
494 * the flow of new requests from CAM to this controller.
495 *
496 * Input: sc -- ptr to OSL internal ctlr context
497 * req_handle -- ptr to request handle sent by OSL.
498 * Output: None
499 * Return value: None
500 */
501 TW_VOID
tw_osli_disallow_new_requests(struct twa_softc * sc,struct tw_cl_req_handle * req_handle)502 tw_osli_disallow_new_requests(struct twa_softc *sc,
503 struct tw_cl_req_handle *req_handle)
504 {
505 /* Only freeze/release the simq for IOs */
506 if (req_handle->is_io) {
507 struct tw_osli_req_context *req = req_handle->osl_req_ctxt;
508 union ccb *ccb = (union ccb *)(req->orig_req);
509
510 xpt_freeze_simq(sc->sim, 1);
511 ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
512 }
513 }
514
515 /*
516 * Function name: tw_osl_timeout
517 * Description: Call to timeout().
518 *
519 * Input: req_handle -- ptr to request handle sent by OSL.
520 * Output: None
521 * Return value: None
522 */
523 TW_VOID
tw_osl_timeout(struct tw_cl_req_handle * req_handle)524 tw_osl_timeout(struct tw_cl_req_handle *req_handle)
525 {
526 struct tw_osli_req_context *req = req_handle->osl_req_ctxt;
527 union ccb *ccb = (union ccb *)(req->orig_req);
528 struct ccb_hdr *ccb_h = &(ccb->ccb_h);
529
530 req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000);
531 }
532
533 /*
534 * Function name: tw_osl_untimeout
535 * Description: Inverse of call to timeout().
536 *
537 * Input: req_handle -- ptr to request handle sent by OSL.
538 * Output: None
539 * Return value: None
540 */
541 TW_VOID
tw_osl_untimeout(struct tw_cl_req_handle * req_handle)542 tw_osl_untimeout(struct tw_cl_req_handle *req_handle)
543 {
544 struct tw_osli_req_context *req = req_handle->osl_req_ctxt;
545
546 req->deadline = 0;
547 }
548
549 /*
550 * Function name: tw_osl_scan_bus
551 * Description: CL calls this function to request for a bus scan.
552 *
553 * Input: ctlr_handle -- ptr to controller handle
554 * Output: None
555 * Return value: None
556 */
557 TW_VOID
tw_osl_scan_bus(struct tw_cl_ctlr_handle * ctlr_handle)558 tw_osl_scan_bus(struct tw_cl_ctlr_handle *ctlr_handle)
559 {
560 struct twa_softc *sc = ctlr_handle->osl_ctlr_ctxt;
561 TW_INT32 error;
562
563 if ((error = tw_osli_request_bus_scan(sc)))
564 tw_osli_printf(sc, "error = %d",
565 TW_CL_SEVERITY_ERROR_STRING,
566 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
567 0x2109,
568 "Bus scan request to CAM failed",
569 error);
570 }
571
572 /*
573 * Function name: tw_osl_complete_io
574 * Description: Called to complete CAM scsi requests.
575 *
576 * Input: req_handle -- ptr to request handle
577 * Output: None
578 * Return value: None
579 */
580 TW_VOID
tw_osl_complete_io(struct tw_cl_req_handle * req_handle)581 tw_osl_complete_io(struct tw_cl_req_handle *req_handle)
582 {
583 struct tw_osli_req_context *req = req_handle->osl_req_ctxt;
584 struct tw_cl_req_packet *req_pkt =
585 (struct tw_cl_req_packet *)(&req->req_pkt);
586 struct tw_cl_scsi_req_packet *scsi_req;
587 struct twa_softc *sc = req->ctlr;
588 union ccb *ccb = (union ccb *)(req->orig_req);
589
590 tw_osli_dbg_dprintf(10, sc, "entering");
591
592 if (req->state != TW_OSLI_REQ_STATE_BUSY)
593 tw_osli_printf(sc, "request = %p, status = %d",
594 TW_CL_SEVERITY_ERROR_STRING,
595 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
596 0x210A,
597 "Unposted command completed!!",
598 req, req->state);
599
600 /*
601 * Remove request from the busy queue. Just mark it complete.
602 * There's no need to move it into the complete queue as we are
603 * going to be done with it right now.
604 */
605 req->state = TW_OSLI_REQ_STATE_COMPLETE;
606 tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q);
607
608 tw_osli_unmap_request(req);
609
610 req->deadline = 0;
611 if (req->error_code) {
612 /* This request never got submitted to the firmware. */
613 if (req->error_code == EBUSY) {
614 /*
615 * Cmd queue is full, or the Common Layer is out of
616 * resources. The simq will already have been frozen.
617 * When this ccb gets completed will unfreeze the simq.
618 */
619 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
620 }
621 else if (req->error_code == EFBIG)
622 ccb->ccb_h.status = CAM_REQ_TOO_BIG;
623 else
624 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
625 } else {
626 scsi_req = &(req_pkt->gen_req_pkt.scsi_req);
627 if (req_pkt->status == TW_CL_ERR_REQ_SUCCESS)
628 ccb->ccb_h.status = CAM_REQ_CMP;
629 else {
630 if (req_pkt->status & TW_CL_ERR_REQ_INVALID_TARGET)
631 ccb->ccb_h.status |= CAM_SEL_TIMEOUT;
632 else if (req_pkt->status & TW_CL_ERR_REQ_INVALID_LUN)
633 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;
634 else if (req_pkt->status & TW_CL_ERR_REQ_SCSI_ERROR)
635 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
636 else if (req_pkt->status & TW_CL_ERR_REQ_BUS_RESET)
637 ccb->ccb_h.status |= (CAM_REQUEUE_REQ | CAM_SCSI_BUS_RESET);
638 /*
639 * If none of the above errors occurred, simply
640 * mark completion error.
641 */
642 if (ccb->ccb_h.status == 0)
643 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
644
645 if (req_pkt->status & TW_CL_ERR_REQ_AUTO_SENSE_VALID) {
646 ccb->csio.sense_len = scsi_req->sense_len;
647 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
648 }
649 }
650
651 ccb->csio.scsi_status = scsi_req->scsi_status;
652 }
653
654 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
655 mtx_lock(sc->sim_lock);
656 xpt_done(ccb);
657 mtx_unlock(sc->sim_lock);
658 if (! req->error_code)
659 /* twa_action will free the request otherwise */
660 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
661 }
662