CAM_NEW_TRAN_CODE fixes.
[dragonfly.git] / sys / dev / raid / twa / twa_cam.c
blob969e45627879a3d965e2bec052086006fca0b045
1 /*-
2 * Copyright (c) 2003-04 3ware, Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
26 * $FreeBSD$
27 * $DragonFly: src/sys/dev/raid/twa/twa_cam.c,v 1.8 2008/01/21 04:30:04 pavalos Exp $
31 * 3ware driver for 9000 series storage controllers.
33 * Author: Vinod Kashyap
37 #include "twa_includes.h"
39 #include <bus/cam/cam.h>
40 #include <bus/cam/cam_ccb.h>
41 #include <bus/cam/cam_sim.h>
42 #include <bus/cam/cam_xpt_sim.h>
43 #include <bus/cam/cam_xpt_periph.h>
44 #include <bus/cam/cam_debug.h>
45 #include <bus/cam/cam_periph.h>
47 #include <bus/cam/scsi/scsi_all.h>
48 #include <bus/cam/scsi/scsi_message.h>
50 static int twa_execute_scsi(struct twa_request *tr, union ccb *ccb);
51 static void twa_action(struct cam_sim *sim, union ccb *ccb);
52 static void twa_poll(struct cam_sim *sim);
53 static void twa_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg);
54 static void twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb);
59 * Function name: twa_cam_setup
60 * Description: Attaches the driver to CAM.
62 * Input: sc -- ptr to per ctlr structure
63 * Output: None
64 * Return value: 0 -- success
65 * non-zero-- failure
67 int
68 twa_cam_setup(struct twa_softc *sc)
70 struct cam_devq *devq;
71 struct ccb_setasync csa;
73 twa_dbg_dprint(3, sc, "sc = %p", sc);
75 * Create the device queue for our SIM.
77 devq = cam_simq_alloc(TWA_Q_LENGTH);
78 if (devq == NULL)
79 return(ENOMEM);
82 * Create a SIM entry. Though we can support TWA_Q_LENGTH simultaneous
83 * requests, we claim to be able to handle only (TWA_Q_LENGTH - 1), so
84 * that we always have a request packet available to service attention
85 * interrupts.
87 twa_dbg_dprint(3, sc, "Calling cam_sim_alloc");
88 sc->twa_sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc,
89 device_get_unit(sc->twa_bus_dev),
90 TWA_Q_LENGTH - 1, 1, devq);
91 cam_simq_release(devq);
92 if (sc->twa_sim == NULL) {
93 return(ENOMEM);
97 * Register the bus.
99 twa_dbg_dprint(3, sc, "Calling xpt_bus_register");
100 if (xpt_bus_register(sc->twa_sim, 0) != CAM_SUCCESS) {
101 cam_sim_free(sc->twa_sim);
102 sc->twa_sim = NULL; /* so twa_cam_detach will not try to free it */
103 return(ENXIO);
106 twa_dbg_dprint(3, sc, "Calling xpt_create_path");
107 if (xpt_create_path(&sc->twa_path, NULL,
108 cam_sim_path(sc->twa_sim),
109 CAM_TARGET_WILDCARD,
110 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
111 xpt_bus_deregister(cam_sim_path (sc->twa_sim));
112 cam_sim_free(sc->twa_sim); /* passing TRUE will free the devq as well */
113 return(ENXIO);
116 twa_dbg_dprint(3, sc, "Calling xpt_setup_ccb");
117 xpt_setup_ccb(&csa.ccb_h, sc->twa_path, 5);
118 csa.ccb_h.func_code = XPT_SASYNC_CB;
119 csa.event_enable = AC_FOUND_DEVICE | AC_LOST_DEVICE;
120 csa.callback = twa_async;
121 csa.callback_arg = sc;
122 xpt_action((union ccb *)&csa);
124 twa_dbg_dprint(3, sc, "Calling twa_request_bus_scan");
126 * Request a bus scan, so that CAM gets to know of
127 * the logical units that we control.
129 twa_request_bus_scan(sc);
130 twa_dbg_dprint(3, sc, "Exiting");
131 return(0);
137 * Function name: twa_cam_detach
138 * Description: Detaches the driver from CAM.
140 * Input: sc -- ptr to per ctlr structure
141 * Output: None
142 * Return value: None
144 void
145 twa_cam_detach(struct twa_softc *sc)
147 if (sc->twa_path)
148 xpt_free_path(sc->twa_path);
149 if (sc->twa_sim) {
150 xpt_bus_deregister(cam_sim_path(sc->twa_sim));
151 cam_sim_free(sc->twa_sim); /* passing TRUE will free the devq as well */
158 * Function name: twa_send_scsi_cmd
159 * Description: Sends down a scsi cmd to fw.
161 * Input: tr -- ptr to request pkt
162 * cmd -- opcode of scsi cmd to send
163 * Output: None
164 * Return value: 0 -- success
165 * non-zero-- failure
168 twa_send_scsi_cmd(struct twa_request *tr, int cmd)
170 union ccb ccb;
172 bzero(&ccb, sizeof(union ccb));
173 ccb.csio.cdb_io.cdb_bytes[0] = (u_int8_t)cmd;
174 ccb.csio.cdb_io.cdb_bytes[4] = 128;
175 ccb.csio.cdb_len = 16;
176 ccb.csio.data_ptr = kmalloc(TWA_SECTOR_SIZE, M_DEVBUF, M_INTWAIT|M_ZERO);
177 ccb.csio.dxfer_len = TWA_SECTOR_SIZE;
179 ccb.ccb_h.target_id = 0;
180 ccb.ccb_h.flags |= CAM_DIR_IN;
182 if (twa_execute_scsi(tr, &ccb))
183 return(EIO);
184 return(0);
190 * Function name: twa_execute_scsi
191 * Description: Build a fw cmd, based on a CAM style ccb, and
192 * send it down.
194 * Input: tr -- ptr to request pkt
195 * ccb -- ptr to CAM style ccb
196 * Output: None
197 * Return value: 0 -- success
198 * non-zero-- failure
201 twa_execute_scsi(struct twa_request *tr, union ccb *ccb)
203 struct twa_softc *sc = tr->tr_sc;
204 struct twa_command_packet *cmdpkt;
205 struct twa_command_9k *cmd9k;
206 struct ccb_hdr *ccb_h = &(ccb->ccb_h);
207 struct ccb_scsiio *csio = &(ccb->csio);
208 int error;
210 twa_dbg_dprint(3, sc, "SCSI I/O request 0x%x",
211 csio->cdb_io.cdb_bytes[0]);
213 if (ccb_h->target_id >= TWA_MAX_UNITS) {
214 twa_dbg_dprint(3, sc, "Invalid target. PTL = %x %x %x",
215 ccb_h->path_id, ccb_h->target_id, ccb_h->target_lun);
216 ccb_h->status |= CAM_TID_INVALID;
217 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL)
218 xpt_done(ccb);
219 return(1);
221 if (ccb_h->target_lun != 0) {
222 twa_dbg_dprint(3, sc, "Invalid lun. PTL = %x %x %x",
223 ccb_h->path_id, ccb_h->target_id, ccb_h->target_lun);
224 ccb_h->status |= CAM_LUN_INVALID;
225 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL)
226 xpt_done(ccb);
227 return(1);
230 if(ccb_h->flags & CAM_CDB_PHYS) {
231 twa_printf(sc, "Physical CDB address!\n");
232 ccb_h->status = CAM_REQ_CMP_ERR;
233 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL)
234 xpt_done(ccb);
235 return(1);
239 * We are going to work on this request. Mark it as enqueued (though
240 * we don't actually queue it...)
242 ccb_h->status |= CAM_SIM_QUEUED;
244 if((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
245 if(ccb_h->flags & CAM_DIR_IN)
246 tr->tr_flags |= TWA_CMD_DATA_IN;
247 else
248 tr->tr_flags |= TWA_CMD_DATA_OUT;
251 cmdpkt = tr->tr_command;
253 cmdpkt->cmd_hdr.header_desc.size_header = 128;
255 cmd9k = &(cmdpkt->command.cmd_pkt_9k);
256 cmd9k->command.opcode = TWA_OP_EXECUTE_SCSI_COMMAND;
257 cmd9k->unit = ccb_h->target_id;
258 cmd9k->request_id = tr->tr_request_id;
259 cmd9k->status = 0;
260 cmd9k->sgl_offset = 16; /* offset from end of hdr = max cdb len */
262 if(ccb_h->flags & CAM_CDB_POINTER)
263 bcopy(csio->cdb_io.cdb_ptr, cmd9k->cdb, csio->cdb_len);
264 else
265 bcopy(csio->cdb_io.cdb_bytes, cmd9k->cdb, csio->cdb_len);
267 if (!(ccb_h->flags & CAM_DATA_PHYS)) {
268 /* Virtual data addresses. Need to convert them... */
269 twa_dbg_dprint(3, sc, "XPT_SCSI_IO: Single virtual address!");
270 if (!(ccb_h->flags & CAM_SCATTER_VALID)) {
271 if (csio->dxfer_len > TWA_MAX_IO_SIZE) {
272 twa_printf(sc, "I/O size %d too big.\n",
273 csio->dxfer_len);
274 ccb_h->status = CAM_REQ_TOO_BIG;
275 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL)
276 xpt_done(ccb);
277 return(1);
280 if ((tr->tr_length = csio->dxfer_len)) {
281 tr->tr_data = csio->data_ptr;
282 cmd9k->sgl_entries = 1;
284 } else {
285 twa_printf(sc, "twa_execute_scsi: XPT_SCSI_IO: Got SGList!\n");
286 ccb_h->status = CAM_REQ_CMP_ERR;
287 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL) {
288 xpt_done(ccb);
290 return(1);
292 } else {
293 /* Data addresses are physical. */
294 twa_printf(sc, "twa_execute_scsi: XPT_SCSI_IO: Physical data addresses!\n");
295 ccb_h->status = CAM_REQ_CMP_ERR;
296 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL) {
297 ccb_h->status |= CAM_RELEASE_SIMQ;
298 ccb_h->status &= ~CAM_SIM_QUEUED;
299 xpt_done(ccb);
301 return(1);
304 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_9K;
305 /* twa_setup_data_dmamap will fill in the SGL, and submit the I/O. */
306 error = twa_map_request(tr);
307 return(error);
313 * Function name: twa_action
314 * Description: Driver entry point for CAM's use.
316 * Input: sim -- sim corresponding to the ctlr
317 * ccb -- ptr to CAM request
318 * Output: None
319 * Return value: None
321 void
322 twa_action(struct cam_sim *sim, union ccb *ccb)
324 struct twa_softc *sc = (struct twa_softc *)cam_sim_softc(sim);
325 struct ccb_hdr *ccb_h = &(ccb->ccb_h);
327 switch (ccb_h->func_code) {
328 case XPT_SCSI_IO: /* SCSI I/O */
330 struct twa_request *tr;
332 if ((sc->twa_state & TWA_STATE_SIMQ_FROZEN) ||
333 ((tr = twa_get_request(sc)) == NULL)) {
334 twa_dbg_dprint(2, sc, "simq frozen/Cannot get request pkt.");
336 * Freeze the simq to maintain ccb ordering. The next
337 * ccb that gets completed will unfreeze the simq.
339 twa_disallow_new_requests(sc);
340 ccb_h->status |= CAM_REQUEUE_REQ;
341 xpt_done(ccb);
342 break;
344 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_EXTERNAL;
345 tr->tr_private = ccb;
346 tr->tr_callback = twa_complete_io;
347 if (twa_execute_scsi(tr, ccb))
348 twa_release_request(tr);
349 break;
352 case XPT_ABORT:
353 twa_dbg_dprint(2, sc, "Abort request");
354 ccb_h->status = CAM_UA_ABORT;
355 xpt_done(ccb);
356 break;
358 case XPT_RESET_BUS:
359 twa_printf(sc, "Reset Bus request from CAM...\n");
360 if (twa_reset(sc)) {
361 twa_printf(sc, "Reset Bus failed!\n");
362 ccb_h->status = CAM_REQ_CMP_ERR;
364 else
365 ccb_h->status = CAM_REQ_CMP;
367 xpt_done(ccb);
368 break;
370 case XPT_SET_TRAN_SETTINGS:
371 twa_dbg_dprint(3, sc, "XPT_SET_TRAN_SETTINGS");
374 * This command is not supported, since it's very specific
375 * to SCSI, and we are doing ATA.
377 ccb_h->status = CAM_FUNC_NOTAVAIL;
378 xpt_done(ccb);
379 break;
381 case XPT_GET_TRAN_SETTINGS:
383 struct ccb_trans_settings *cts = &ccb->cts;
384 #ifdef CAM_NEW_TRAN_CODE
385 struct ccb_trans_settings_scsi *scsi =
386 &cts->proto_specific.scsi;
387 struct ccb_trans_settings_spi *spi =
388 &cts->xport_specific.spi;
390 cts->protocol = PROTO_SCSI;
391 cts->protocol_version = SCSI_REV_2;
392 cts->transport = XPORT_SPI;
393 cts->transport_version = 2;
395 spi->valid = CTS_SPI_VALID_DISC;
396 spi->flags = CTS_SPI_FLAGS_DISC_ENB;
397 scsi->valid = CTS_SCSI_VALID_TQ;
398 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
399 #else
400 cts->valid = (CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID);
401 cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
402 #endif
403 twa_dbg_dprint(3, sc, "XPT_GET_TRAN_SETTINGS");
404 ccb_h->status = CAM_REQ_CMP;
405 xpt_done(ccb);
406 break;
409 case XPT_CALC_GEOMETRY:
411 struct ccb_calc_geometry *geom;
413 twa_dbg_dprint(3, sc, "XPT_CALC_GEOMETRY request");
414 geom = &ccb->ccg;
416 if (geom->volume_size > 0x200000) /* 1 GB */ {
417 geom->heads = 255;
418 geom->secs_per_track = 63;
419 } else {
420 geom->heads = 64;
421 geom->secs_per_track = 32;
423 geom->cylinders = geom->volume_size /
424 (geom->heads * geom->secs_per_track);
425 ccb_h->status = CAM_REQ_CMP;
426 xpt_done(ccb);
427 break;
430 case XPT_PATH_INQ: /* Path inquiry -- get twa properties */
432 struct ccb_pathinq *path_inq = &ccb->cpi;
434 twa_dbg_dprint(3, sc, "XPT_PATH_INQ request");
436 path_inq->version_num = 1;
437 path_inq->hba_inquiry = 0;
438 path_inq->target_sprt = 0;
439 path_inq->hba_misc = 0;
440 path_inq->hba_eng_cnt = 0;
441 path_inq->max_target = TWA_MAX_UNITS;
442 path_inq->max_lun = 0;
443 path_inq->unit_number = cam_sim_unit(sim);
444 path_inq->bus_id = cam_sim_bus(sim);
445 path_inq->initiator_id = 12;
446 path_inq->base_transfer_speed = 100000;
447 strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN);
448 strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN);
449 strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN);
450 #ifdef CAM_NEW_TRAN_CODE
451 path_inq->transport = XPORT_SPI;
452 path_inq->transport_version = 2;
453 path_inq->protocol = PROTO_SCSI;
454 path_inq->protocol_version = SCSI_REV_2;
455 #endif
456 ccb_h->status = CAM_REQ_CMP;
457 xpt_done(ccb);
458 break;
461 default:
462 twa_dbg_dprint(3, sc, "func_code = %x", ccb_h->func_code);
463 ccb_h->status = CAM_REQ_INVALID;
464 xpt_done(ccb);
465 break;
472 * Function name: twa_poll
473 * Description: Driver entry point called when interrupts are not available.
475 * Input: sim -- sim corresponding to the controller
476 * Output: None
477 * Return value: None
479 void
480 twa_poll(struct cam_sim *sim)
482 #ifdef TWA_DEBUG
483 struct twa_softc *sc = (struct twa_softc *)cam_sim_softc(sim);
484 #endif /* TWA_DEBUG */
486 twa_dbg_dprint(3, sc, "Entering sc = %p", sc);
487 twa_interrupt(cam_sim_softc(sim));
488 twa_dbg_dprint(3, sc, "Exiting sc = %p", sc);
494 * Function name: twa_async
495 * Description: Driver entry point for CAM to notify driver of special
496 * events. We don't use this for now.
498 * Input: callback_arg -- ptr to per ctlr structure
499 * code -- code associated with the event
500 * path -- cam path
501 * arg --
502 * Output: None
503 * Return value: 0 -- success
504 * non-zero-- failure
506 void
507 twa_async(void *callback_arg, u_int32_t code,
508 struct cam_path *path, void *arg)
510 #ifdef TWA_DEBUG
511 struct twa_softc *sc = (struct twa_softc *)callback_arg;
512 #endif /* TWA_DEBUG */
514 twa_dbg_dprint(3, sc, "sc = %p, code = %x, path = %p, arg = %p",
515 sc, code, path, arg);
521 * Function name: twa_request_bus_scan
522 * Description: Requests CAM for a scan of the bus.
524 * Input: sc -- ptr to per ctlr structure
525 * Output: None
526 * Return value: None
528 void
529 twa_request_bus_scan(struct twa_softc *sc)
531 struct cam_path *path;
532 union ccb *ccb;
534 ccb = kmalloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO);
535 if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->twa_sim),
536 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP)
537 return;
539 xpt_setup_ccb(&ccb->ccb_h, path, 5);
540 ccb->ccb_h.func_code = XPT_SCAN_BUS;
541 ccb->ccb_h.cbfcnp = twa_bus_scan_cb;
542 ccb->crcn.flags = CAM_FLAG_NONE;
543 xpt_action(ccb);
549 * Function name: twa_bus_scan_cb
550 * Description: Callback from CAM on a bus scan request.
552 * Input: periph -- we don't use this
553 * ccb -- bus scan request ccb that we sent to CAM
554 * Output: None
555 * Return value: None
557 static void
558 twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb)
560 twa_dbg_print(3, "ccb = %p\n", ccb);
561 if (ccb->ccb_h.status != CAM_REQ_CMP)
562 kprintf("cam_scan_callback: failure status = %x\n",
563 ccb->ccb_h.status);
564 else
565 twa_dbg_print(3, "success");
567 xpt_free_path(ccb->ccb_h.path);
568 kfree(ccb, M_TEMP);
574 * Function name: twa_scsi_complete
575 * Description: Called to complete CAM scsi requests.
577 * Input: tr -- ptr to request pkt to be completed
578 * Output: None
579 * Return value: None
581 void
582 twa_scsi_complete(struct twa_request *tr)
584 struct twa_softc *sc = tr->tr_sc;
585 struct twa_command_header *cmd_hdr = &(tr->tr_command->cmd_hdr);
586 struct twa_command_9k *cmd = &(tr->tr_command->command.cmd_pkt_9k);
587 union ccb *ccb = (union ccb *)(tr->tr_private);
588 u_int16_t error;
589 u_int8_t *cdb;
591 if (tr->tr_error) {
592 if (tr->tr_error == EBUSY)
593 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
594 else if (tr->tr_error == EFBIG)
595 ccb->ccb_h.status = CAM_REQ_TOO_BIG;
596 else
597 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
598 } else {
599 if (cmd->status) {
600 twa_dbg_dprint(1, sc, "req_id = 0x%x, status = 0x%x",
601 cmd->request_id,
602 cmd->status);
604 error = cmd_hdr->status_block.error;
605 if ((error == TWA_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) ||
606 (error == TWA_ERROR_UNIT_OFFLINE)) {
607 twa_dbg_dprint(3, sc, "Unsupported unit. PTL = %x %x %x",
608 ccb->ccb_h.path_id,
609 ccb->ccb_h.target_id,
610 ccb->ccb_h.target_lun);
611 ccb->ccb_h.status |= CAM_TID_INVALID;
612 } else {
613 twa_dbg_dprint(2, sc, "cmd = %x %x %x %x %x %x %x",
614 cmd->command.opcode,
615 cmd->command.reserved,
616 cmd->unit,
617 cmd->request_id,
618 cmd->status,
619 cmd->sgl_offset,
620 cmd->sgl_entries);
622 cdb = (u_int8_t *)(cmd->cdb);
623 twa_dbg_dprint(2, sc, "cdb = %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
624 cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
625 cdb[8], cdb[9], cdb[10], cdb[11], cdb[12], cdb[13], cdb[14], cdb[15]);
627 cmd_hdr->err_specific_desc[sizeof(cmd_hdr->err_specific_desc) - 1] = '\0';
629 * Print the error. Firmware doesn't yet support
630 * the 'Mode Sense' cmd. Don't print if the cmd
631 * is 'Mode Sense', and the error is 'Invalid field
632 * in CDB'.
634 if (! ((cdb[0] == 0x1A) && (error == 0x10D)))
635 twa_printf(sc, "SCSI cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
636 cdb[0],
637 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
638 error,
639 twa_find_msg_string(twa_error_table, error),
640 cmd_hdr->err_specific_desc);
643 bcopy(cmd_hdr->sense_data, &(ccb->csio.sense_data),
644 TWA_SENSE_DATA_LENGTH);
645 ccb->csio.sense_len = TWA_SENSE_DATA_LENGTH;
646 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
647 } else
648 ccb->ccb_h.status = CAM_REQ_CMP;
650 ccb->csio.scsi_status = cmd->status;
651 /* If simq is frozen, unfreeze it. */
652 if (sc->twa_state & TWA_STATE_SIMQ_FROZEN)
653 twa_allow_new_requests(sc, (void *)ccb);
656 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
657 xpt_done(ccb);
663 * Function name: twa_drain_busy_queue
664 * Description: This function gets called after a controller reset.
665 * It errors back to CAM, all those requests that were
666 * pending with the firmware, at the time of the reset.
668 * Input: sc -- ptr to per ctlr structure
669 * Output: None
670 * Return value: None
672 void
673 twa_drain_busy_queue(struct twa_softc *sc)
675 struct twa_request *tr;
676 union ccb *ccb;
678 /* Walk the busy queue. */
679 while ((tr = twa_dequeue_busy(sc))) {
680 twa_unmap_request(tr);
681 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_INTERNAL) ||
682 (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_IOCTL)) {
683 /* It's an internal/ioctl request. Simply free it. */
684 if (tr->tr_data)
685 kfree(tr->tr_data, M_DEVBUF);
686 } else {
687 if ((ccb = tr->tr_private)) {
688 /* It's a SCSI request. Complete it. */
689 ccb->ccb_h.status = CAM_SCSI_BUS_RESET |
690 CAM_RELEASE_SIMQ;
691 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
692 xpt_done(ccb);
695 twa_release_request(tr);
702 * Function name: twa_allow_new_requests
703 * Description: Sets the appropriate status bits in a ccb such that,
704 * when the ccb is completed by a call to xpt_done,
705 * CAM knows that it's ok to unfreeze the flow of new
706 * requests to this controller, if the flow is frozen.
708 * Input: sc -- ptr to per ctlr structure
709 * ccb -- ptr to CAM request
710 * Output: None
711 * Return value: None
713 void
714 twa_allow_new_requests(struct twa_softc *sc, void *ccb)
716 ((union ccb *)(ccb))->ccb_h.status |= CAM_RELEASE_SIMQ;
717 sc->twa_state &= ~TWA_STATE_SIMQ_FROZEN;
723 * Function name: twa_disallow_new_requests
724 * Description: Calls the appropriate CAM function, so as to freeze
725 * the flow of new requests from CAM to this controller.
727 * Input: sc -- ptr to per ctlr structure
728 * Output: None
729 * Return value: None
731 void
732 twa_disallow_new_requests(struct twa_softc *sc)
734 xpt_freeze_simq(sc->twa_sim, 1);
735 sc->twa_state |= TWA_STATE_SIMQ_FROZEN;