Make CAM_NEW_TRAN_CODE default.
[dragonfly.git] / sys / dev / raid / twa / twa_cam.c
1 /*-
2  * Copyright (c) 2003-04 3ware, Inc.
3  * All rights reserved.
4  *
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.
13  *
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.
25  *
26  *      $FreeBSD$
27  * $DragonFly: src/sys/dev/raid/twa/twa_cam.c,v 1.9 2008/02/10 00:01:03 pavalos Exp $
28  */
29
30 /*
31  * 3ware driver for 9000 series storage controllers.
32  *
33  * Author: Vinod Kashyap
34  */
35
36
37 #include "twa_includes.h"
38
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>
46
47 #include <bus/cam/scsi/scsi_all.h>
48 #include <bus/cam/scsi/scsi_message.h>
49
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);
55
56
57
58 /*
59  * Function name:       twa_cam_setup
60  * Description:         Attaches the driver to CAM.
61  *
62  * Input:               sc      -- ptr to per ctlr structure
63  * Output:              None
64  * Return value:        0       -- success
65  *                      non-zero-- failure
66  */
67 int
68 twa_cam_setup(struct twa_softc *sc)
69 {
70         struct cam_devq         *devq;
71         struct ccb_setasync     csa;
72
73         twa_dbg_dprint(3, sc, "sc = %p", sc);
74         /*
75          * Create the device queue for our SIM.
76          */
77         devq = cam_simq_alloc(TWA_Q_LENGTH);
78         if (devq == NULL)
79                 return(ENOMEM);
80
81         /*
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.
86          */
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);
94         }
95
96         /*
97          * Register the bus.
98          */
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);
104         }
105
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);
114         }
115
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);
123
124         twa_dbg_dprint(3, sc, "Calling twa_request_bus_scan");
125         /*
126          * Request a bus scan, so that CAM gets to know of
127          * the logical units that we control.
128          */
129         twa_request_bus_scan(sc);
130         twa_dbg_dprint(3, sc, "Exiting");
131         return(0);
132 }
133
134
135
136 /*
137  * Function name:       twa_cam_detach
138  * Description:         Detaches the driver from CAM.
139  *
140  * Input:               sc      -- ptr to per ctlr structure
141  * Output:              None
142  * Return value:        None
143  */
144 void
145 twa_cam_detach(struct twa_softc *sc)
146 {
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 */
152         }
153 }
154
155
156
157 /*
158  * Function name:       twa_send_scsi_cmd
159  * Description:         Sends down a scsi cmd to fw.
160  *
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
166  */
167 int
168 twa_send_scsi_cmd(struct twa_request *tr, int cmd)
169 {
170         union ccb       ccb;
171
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;
178
179         ccb.ccb_h.target_id = 0;
180         ccb.ccb_h.flags |= CAM_DIR_IN;
181
182         if (twa_execute_scsi(tr, &ccb))
183                 return(EIO);
184         return(0);
185 }
186
187
188
189 /*
190  * Function name:       twa_execute_scsi
191  * Description:         Build a fw cmd, based on a CAM style ccb, and
192  *                      send it down.
193  *
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
199  */
200 int
201 twa_execute_scsi(struct twa_request *tr, union ccb *ccb)
202 {
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;
209
210         twa_dbg_dprint(3, sc, "SCSI I/O request 0x%x", 
211                                 csio->cdb_io.cdb_bytes[0]);
212
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);
220         }
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);
228         }
229
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);
236         }
237
238         /*
239          * We are going to work on this request.  Mark it as enqueued (though
240          * we don't actually queue it...)
241          */
242         ccb_h->status |= CAM_SIM_QUEUED;
243
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;
249         }
250
251         cmdpkt = tr->tr_command;
252
253         cmdpkt->cmd_hdr.header_desc.size_header = 128;
254                 
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 */
261
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);
266
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);
278                         }
279
280                         if ((tr->tr_length = csio->dxfer_len)) {
281                                 tr->tr_data = csio->data_ptr;
282                                 cmd9k->sgl_entries = 1;
283                         }
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);
289                         }
290                         return(1);
291                 }
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);
300                 }
301                 return(1);
302         }
303
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);
308 }
309
310
311
312 /*
313  * Function name:       twa_action
314  * Description:         Driver entry point for CAM's use.
315  *
316  * Input:               sim     -- sim corresponding to the ctlr
317  *                      ccb     -- ptr to CAM request
318  * Output:              None
319  * Return value:        None
320  */
321 void
322 twa_action(struct cam_sim *sim, union ccb *ccb)
323 {
324         struct twa_softc        *sc = (struct twa_softc *)cam_sim_softc(sim);
325         struct ccb_hdr          *ccb_h = &(ccb->ccb_h);
326
327         switch (ccb_h->func_code) {
328         case XPT_SCSI_IO:       /* SCSI I/O */
329         {
330                 struct twa_request      *tr;
331
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.");
335                         /*
336                          * Freeze the simq to maintain ccb ordering.  The next
337                          * ccb that gets completed will unfreeze the simq.
338                          */
339                         twa_disallow_new_requests(sc);
340                         ccb_h->status |= CAM_REQUEUE_REQ;
341                         xpt_done(ccb);
342                         break;
343                 }
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;
350         }
351
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;
357
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;
363                 }
364                 else
365                         ccb_h->status = CAM_REQ_CMP;
366
367                 xpt_done(ccb);
368                 break;
369
370         case XPT_SET_TRAN_SETTINGS:
371                 twa_dbg_dprint(3, sc, "XPT_SET_TRAN_SETTINGS");
372
373                 /*
374                  * This command is not supported, since it's very specific
375                  * to SCSI, and we are doing ATA.
376                  */
377                 ccb_h->status = CAM_FUNC_NOTAVAIL;
378                 xpt_done(ccb);
379                 break;
380
381         case XPT_GET_TRAN_SETTINGS: 
382         {
383                 struct ccb_trans_settings       *cts = &ccb->cts;
384                 struct ccb_trans_settings_scsi *scsi =
385                     &cts->proto_specific.scsi;
386                 struct ccb_trans_settings_spi *spi =
387                     &cts->xport_specific.spi;
388
389                 cts->protocol = PROTO_SCSI;
390                 cts->protocol_version = SCSI_REV_2;
391                 cts->transport = XPORT_SPI;
392                 cts->transport_version = 2;
393
394                 spi->valid = CTS_SPI_VALID_DISC;
395                 spi->flags = CTS_SPI_FLAGS_DISC_ENB;
396                 scsi->valid = CTS_SCSI_VALID_TQ;
397                 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
398                 twa_dbg_dprint(3, sc, "XPT_GET_TRAN_SETTINGS");
399                 ccb_h->status = CAM_REQ_CMP;
400                 xpt_done(ccb);
401                 break;
402         }
403
404         case XPT_CALC_GEOMETRY:
405         {
406                 struct ccb_calc_geometry        *geom;
407
408                 twa_dbg_dprint(3, sc, "XPT_CALC_GEOMETRY request");
409                 geom = &ccb->ccg;
410
411                 if (geom->volume_size > 0x200000) /* 1 GB */ {
412                         geom->heads = 255;
413                         geom->secs_per_track = 63;
414                 } else {
415                         geom->heads = 64;
416                         geom->secs_per_track = 32;
417                 }
418                 geom->cylinders = geom->volume_size /
419                                         (geom->heads * geom->secs_per_track);
420                 ccb_h->status = CAM_REQ_CMP;
421                 xpt_done(ccb);
422                 break;
423         }
424
425         case XPT_PATH_INQ:    /* Path inquiry -- get twa properties */
426         {
427                 struct ccb_pathinq      *path_inq = &ccb->cpi;
428
429                 twa_dbg_dprint(3, sc, "XPT_PATH_INQ request");
430
431                 path_inq->version_num = 1;
432                 path_inq->hba_inquiry = 0;
433                 path_inq->target_sprt = 0;
434                 path_inq->hba_misc = 0;
435                 path_inq->hba_eng_cnt = 0;
436                 path_inq->max_target = TWA_MAX_UNITS;
437                 path_inq->max_lun = 0;
438                 path_inq->unit_number = cam_sim_unit(sim);
439                 path_inq->bus_id = cam_sim_bus(sim);
440                 path_inq->initiator_id = 12;
441                 path_inq->base_transfer_speed = 100000;
442                 strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN);
443                 strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN);
444                 strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN);
445                 path_inq->transport = XPORT_SPI;
446                 path_inq->transport_version = 2;
447                 path_inq->protocol = PROTO_SCSI;
448                 path_inq->protocol_version = SCSI_REV_2;
449                 ccb_h->status = CAM_REQ_CMP;
450                 xpt_done(ccb);
451                 break;
452         }
453
454         default:
455                 twa_dbg_dprint(3, sc, "func_code = %x", ccb_h->func_code);
456                 ccb_h->status = CAM_REQ_INVALID;
457                 xpt_done(ccb);
458                 break;
459         }
460 }
461
462
463
464 /*
465  * Function name:       twa_poll
466  * Description:         Driver entry point called when interrupts are not available.
467  *
468  * Input:               sim     -- sim corresponding to the controller
469  * Output:              None
470  * Return value:        None
471  */
472 void
473 twa_poll(struct cam_sim *sim)
474 {
475 #ifdef TWA_DEBUG
476         struct twa_softc *sc = (struct twa_softc *)cam_sim_softc(sim);
477 #endif /* TWA_DEBUG */
478
479         twa_dbg_dprint(3, sc, "Entering sc = %p", sc);
480         twa_interrupt(cam_sim_softc(sim));
481         twa_dbg_dprint(3, sc, "Exiting sc = %p", sc);
482 }
483
484
485
486 /*
487  * Function name:       twa_async
488  * Description:         Driver entry point for CAM to notify driver of special
489  *                      events.  We don't use this for now.
490  *
491  * Input:               callback_arg    -- ptr to per ctlr structure
492  *                      code            -- code associated with the event
493  *                      path            -- cam path
494  *                      arg             -- 
495  * Output:              None
496  * Return value:        0       -- success
497  *                      non-zero-- failure
498  */
499 void
500 twa_async(void *callback_arg, u_int32_t code, 
501                         struct cam_path *path, void *arg)
502 {
503 #ifdef TWA_DEBUG
504         struct twa_softc *sc = (struct twa_softc *)callback_arg;
505 #endif /* TWA_DEBUG */
506
507         twa_dbg_dprint(3, sc, "sc = %p, code = %x, path = %p, arg = %p",
508                                 sc, code, path, arg);
509 }
510
511
512
513 /*
514  * Function name:       twa_request_bus_scan
515  * Description:         Requests CAM for a scan of the bus.
516  *
517  * Input:               sc      -- ptr to per ctlr structure
518  * Output:              None
519  * Return value:        None
520  */
521 void
522 twa_request_bus_scan(struct twa_softc *sc)
523 {
524         struct cam_path *path;
525         union ccb       *ccb;
526
527         ccb = kmalloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO);
528         if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->twa_sim),
529                         CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP)
530                 return;
531
532         xpt_setup_ccb(&ccb->ccb_h, path, 5);
533         ccb->ccb_h.func_code = XPT_SCAN_BUS;
534         ccb->ccb_h.cbfcnp = twa_bus_scan_cb;
535         ccb->crcn.flags = CAM_FLAG_NONE;
536         xpt_action(ccb);
537 }
538
539
540
541 /*
542  * Function name:       twa_bus_scan_cb
543  * Description:         Callback from CAM on a bus scan request.
544  *
545  * Input:               periph  -- we don't use this
546  *                      ccb     -- bus scan request ccb that we sent to CAM
547  * Output:              None
548  * Return value:        None
549  */
550 static void
551 twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb)
552 {
553         twa_dbg_print(3, "ccb = %p\n", ccb);
554         if (ccb->ccb_h.status != CAM_REQ_CMP)
555                 kprintf("cam_scan_callback: failure status = %x\n",
556                                         ccb->ccb_h.status);
557         else
558                 twa_dbg_print(3, "success");
559
560         xpt_free_path(ccb->ccb_h.path);
561         kfree(ccb, M_TEMP);
562 }
563
564
565
566 /*
567  * Function name:       twa_scsi_complete
568  * Description:         Called to complete CAM scsi requests.
569  *
570  * Input:               tr      -- ptr to request pkt to be completed
571  * Output:              None
572  * Return value:        None
573  */
574 void
575 twa_scsi_complete(struct twa_request *tr)
576 {
577         struct twa_softc                *sc = tr->tr_sc;
578         struct twa_command_header       *cmd_hdr = &(tr->tr_command->cmd_hdr);
579         struct twa_command_9k           *cmd = &(tr->tr_command->command.cmd_pkt_9k);
580         union ccb                       *ccb = (union ccb *)(tr->tr_private);
581         u_int16_t                       error;
582         u_int8_t                        *cdb;
583
584         if (tr->tr_error) {
585                 if (tr->tr_error == EBUSY)
586                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
587                 else if (tr->tr_error == EFBIG)
588                         ccb->ccb_h.status = CAM_REQ_TOO_BIG;
589                 else
590                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
591         } else {
592                 if (cmd->status) {
593                         twa_dbg_dprint(1, sc, "req_id = 0x%x, status = 0x%x",
594                                                 cmd->request_id,
595                                                 cmd->status);
596
597                         error = cmd_hdr->status_block.error;
598                         if ((error == TWA_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) ||
599                                         (error == TWA_ERROR_UNIT_OFFLINE)) {
600                                 twa_dbg_dprint(3, sc, "Unsupported unit. PTL = %x %x %x",
601                                                         ccb->ccb_h.path_id,
602                                                         ccb->ccb_h.target_id,
603                                                         ccb->ccb_h.target_lun);
604                                 ccb->ccb_h.status |= CAM_TID_INVALID;
605                         } else {
606                                 twa_dbg_dprint(2, sc, "cmd = %x %x %x %x %x %x %x",
607                                                 cmd->command.opcode,
608                                                 cmd->command.reserved,
609                                                 cmd->unit,
610                                                 cmd->request_id,
611                                                 cmd->status,
612                                                 cmd->sgl_offset,
613                                                 cmd->sgl_entries);
614
615                                 cdb = (u_int8_t *)(cmd->cdb);
616                                 twa_dbg_dprint(2, sc, "cdb = %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
617                                         cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
618                                         cdb[8], cdb[9], cdb[10], cdb[11], cdb[12], cdb[13], cdb[14], cdb[15]);
619
620                                 cmd_hdr->err_specific_desc[sizeof(cmd_hdr->err_specific_desc) - 1] = '\0';
621                                 /* 
622                                  * Print the error. Firmware doesn't yet support
623                                  * the 'Mode Sense' cmd.  Don't print if the cmd
624                                  * is 'Mode Sense', and the error is 'Invalid field
625                                  * in CDB'.
626                                  */
627                                 if (! ((cdb[0] == 0x1A) && (error == 0x10D)))
628                                         twa_printf(sc, "SCSI cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
629                                                 cdb[0],
630                                                 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
631                                                 error,
632                                                 twa_find_msg_string(twa_error_table, error),
633                                                 cmd_hdr->err_specific_desc);
634                         }
635
636                         bcopy(cmd_hdr->sense_data, &(ccb->csio.sense_data),
637                                                 TWA_SENSE_DATA_LENGTH);
638                         ccb->csio.sense_len = TWA_SENSE_DATA_LENGTH;
639                         ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
640                 } else
641                         ccb->ccb_h.status = CAM_REQ_CMP;
642
643                 ccb->csio.scsi_status = cmd->status;
644                 /* If simq is frozen, unfreeze it. */
645                 if (sc->twa_state & TWA_STATE_SIMQ_FROZEN)
646                         twa_allow_new_requests(sc, (void *)ccb);
647         }
648
649         ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
650         xpt_done(ccb);
651 }
652
653
654
655 /*
656  * Function name:       twa_drain_busy_queue
657  * Description:         This function gets called after a controller reset.
658  *                      It errors back to CAM, all those requests that were
659  *                      pending with the firmware, at the time of the reset.
660  *
661  * Input:               sc      -- ptr to per ctlr structure
662  * Output:              None
663  * Return value:        None
664  */
665 void
666 twa_drain_busy_queue(struct twa_softc *sc)
667 {
668         struct twa_request      *tr;
669         union ccb               *ccb;
670
671         /* Walk the busy queue. */
672         while ((tr = twa_dequeue_busy(sc))) {
673                 twa_unmap_request(tr);
674                 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_INTERNAL) ||
675                         (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_IOCTL)) {
676                         /* It's an internal/ioctl request.  Simply free it. */
677                         if (tr->tr_data)
678                                 kfree(tr->tr_data, M_DEVBUF);
679                 } else {
680                         if ((ccb = tr->tr_private)) {
681                                 /* It's a SCSI request.  Complete it. */
682                                 ccb->ccb_h.status = CAM_SCSI_BUS_RESET |
683                                                         CAM_RELEASE_SIMQ;
684                                 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
685                                 xpt_done(ccb);
686                         }
687                 }
688                 twa_release_request(tr);
689         }
690 }
691
692
693
694 /*
695  * Function name:       twa_allow_new_requests
696  * Description:         Sets the appropriate status bits in a ccb such that,
697  *                      when the ccb is completed by a call to xpt_done,
698  *                      CAM knows that it's ok to unfreeze the flow of new
699  *                      requests to this controller, if the flow is frozen.
700  *
701  * Input:               sc      -- ptr to per ctlr structure
702  *                      ccb     -- ptr to CAM request
703  * Output:              None
704  * Return value:        None
705  */
706 void
707 twa_allow_new_requests(struct twa_softc *sc, void *ccb)
708 {
709         ((union ccb *)(ccb))->ccb_h.status |= CAM_RELEASE_SIMQ;
710         sc->twa_state &= ~TWA_STATE_SIMQ_FROZEN;
711 }
712
713
714
715 /*
716  * Function name:       twa_disallow_new_requests
717  * Description:         Calls the appropriate CAM function, so as to freeze
718  *                      the flow of new requests from CAM to this controller.
719  *
720  * Input:               sc      -- ptr to per ctlr structure
721  * Output:              None
722  * Return value:        None
723  */
724 void
725 twa_disallow_new_requests(struct twa_softc *sc)
726 {
727         xpt_freeze_simq(sc->twa_sim, 1);
728         sc->twa_state |= TWA_STATE_SIMQ_FROZEN;
729 }