18d7b838eSMatt Jacob /*-
28d7b838eSMatt Jacob * Copyright (c) 2010 by Panasas, Inc.
38d7b838eSMatt Jacob * All rights reserved.
48d7b838eSMatt Jacob *
58d7b838eSMatt Jacob * Redistribution and use in source and binary forms, with or without
68d7b838eSMatt Jacob * modification, are permitted provided that the following conditions
78d7b838eSMatt Jacob * are met:
88d7b838eSMatt Jacob * 1. Redistributions of source code must retain the above copyright
98d7b838eSMatt Jacob * notice immediately at the beginning of the file, without modification,
108d7b838eSMatt Jacob * this list of conditions, and the following disclaimer.
118d7b838eSMatt Jacob * 2. The name of the author may not be used to endorse or promote products
128d7b838eSMatt Jacob * derived from this software without specific prior written permission.
138d7b838eSMatt Jacob *
148d7b838eSMatt Jacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
158d7b838eSMatt Jacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168d7b838eSMatt Jacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
178d7b838eSMatt Jacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
188d7b838eSMatt Jacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
198d7b838eSMatt Jacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
208d7b838eSMatt Jacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
218d7b838eSMatt Jacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
228d7b838eSMatt Jacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
238d7b838eSMatt Jacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
248d7b838eSMatt Jacob * SUCH DAMAGE.
258d7b838eSMatt Jacob */
268d7b838eSMatt Jacob /*
278d7b838eSMatt Jacob * "Faulty" Device. Victimize random commands with a Selection Timeout.
288d7b838eSMatt Jacob */
298d7b838eSMatt Jacob #include "vhba.h"
308d7b838eSMatt Jacob
318d7b838eSMatt Jacob #define MAX_TGT VHBA_MAXTGT
328d7b838eSMatt Jacob #define MAX_LUN 4
338d7b838eSMatt Jacob
348d7b838eSMatt Jacob #define DISK_SIZE 32
358d7b838eSMatt Jacob #define DISK_SHIFT 9
368d7b838eSMatt Jacob #define DISK_NBLKS ((DISK_SIZE << 20) >> DISK_SHIFT)
378d7b838eSMatt Jacob #define PSEUDO_SPT 64
388d7b838eSMatt Jacob #define PSEUDO_HDS 64
398d7b838eSMatt Jacob #define PSEUDO_SPC (PSEUDO_SPT * PSEUDO_HDS)
408d7b838eSMatt Jacob
418d7b838eSMatt Jacob typedef struct {
428d7b838eSMatt Jacob vhba_softc_t * vhba;
438d7b838eSMatt Jacob uint8_t * disk;
448d7b838eSMatt Jacob size_t disk_size;
458d7b838eSMatt Jacob uint32_t ctr;
468d7b838eSMatt Jacob uint32_t dead;
478d7b838eSMatt Jacob struct task qt;
488d7b838eSMatt Jacob } faulty_t;
498d7b838eSMatt Jacob
508d7b838eSMatt Jacob static void vhba_task(void *, int);
518d7b838eSMatt Jacob static void faulty_act(faulty_t *, struct ccb_scsiio *);
528d7b838eSMatt Jacob
538d7b838eSMatt Jacob void
vhba_init(vhba_softc_t * vhba)548d7b838eSMatt Jacob vhba_init(vhba_softc_t *vhba)
558d7b838eSMatt Jacob {
568d7b838eSMatt Jacob static faulty_t vhbastatic;
578d7b838eSMatt Jacob vhbastatic.vhba = vhba;
588d7b838eSMatt Jacob vhbastatic.disk_size = DISK_SIZE << 20;
598d7b838eSMatt Jacob vhbastatic.disk = malloc(vhbastatic.disk_size, M_DEVBUF, M_WAITOK|M_ZERO);
608d7b838eSMatt Jacob vhba->private = &vhbastatic;
618d7b838eSMatt Jacob vhbastatic.ctr = (arc4random() & 0xffff) + 1;
628d7b838eSMatt Jacob TASK_INIT(&vhbastatic.qt, 0, vhba_task, &vhbastatic);
638d7b838eSMatt Jacob }
648d7b838eSMatt Jacob
658d7b838eSMatt Jacob
668d7b838eSMatt Jacob void
vhba_fini(vhba_softc_t * vhba)678d7b838eSMatt Jacob vhba_fini(vhba_softc_t *vhba)
688d7b838eSMatt Jacob {
698d7b838eSMatt Jacob faulty_t *vhbas = vhba->private;
708d7b838eSMatt Jacob vhba->private = NULL;
718d7b838eSMatt Jacob free(vhbas->disk, M_DEVBUF);
728d7b838eSMatt Jacob }
738d7b838eSMatt Jacob
748d7b838eSMatt Jacob void
vhba_kick(vhba_softc_t * vhba)758d7b838eSMatt Jacob vhba_kick(vhba_softc_t *vhba)
768d7b838eSMatt Jacob {
778d7b838eSMatt Jacob faulty_t *vhbas = vhba->private;
788d7b838eSMatt Jacob taskqueue_enqueue(taskqueue_swi, &vhbas->qt);
798d7b838eSMatt Jacob }
808d7b838eSMatt Jacob
818d7b838eSMatt Jacob static void
vhba_task(void * arg,int pending)828d7b838eSMatt Jacob vhba_task(void *arg, int pending)
838d7b838eSMatt Jacob {
848d7b838eSMatt Jacob faulty_t *vhbas = arg;
858d7b838eSMatt Jacob struct ccb_hdr *ccbh;
868d7b838eSMatt Jacob
878d7b838eSMatt Jacob mtx_lock(&vhbas->vhba->lock);
888d7b838eSMatt Jacob while ((ccbh = TAILQ_FIRST(&vhbas->vhba->actv)) != NULL) {
898d7b838eSMatt Jacob TAILQ_REMOVE(&vhbas->vhba->actv, ccbh, sim_links.tqe);
908d7b838eSMatt Jacob faulty_act(vhbas, (struct ccb_scsiio *)ccbh);
918d7b838eSMatt Jacob if (--vhbas->ctr == 0) {
928d7b838eSMatt Jacob vhbas->dead = 1;
938d7b838eSMatt Jacob vhbas->ctr = (arc4random() & 0xff) + 1;
948d7b838eSMatt Jacob }
958d7b838eSMatt Jacob }
968d7b838eSMatt Jacob while ((ccbh = TAILQ_FIRST(&vhbas->vhba->done)) != NULL) {
978d7b838eSMatt Jacob TAILQ_REMOVE(&vhbas->vhba->done, ccbh, sim_links.tqe);
988d7b838eSMatt Jacob xpt_done((union ccb *)ccbh);
998d7b838eSMatt Jacob }
1008d7b838eSMatt Jacob mtx_unlock(&vhbas->vhba->lock);
1018d7b838eSMatt Jacob }
1028d7b838eSMatt Jacob
1038d7b838eSMatt Jacob static void
faulty_act(faulty_t * vhbas,struct ccb_scsiio * csio)1048d7b838eSMatt Jacob faulty_act(faulty_t *vhbas, struct ccb_scsiio *csio)
1058d7b838eSMatt Jacob {
1068d7b838eSMatt Jacob char junk[128];
1078d7b838eSMatt Jacob cam_status camstatus;
1088d7b838eSMatt Jacob uint8_t *cdb, *ptr, status;
1098d7b838eSMatt Jacob uint32_t data_len;
1108d7b838eSMatt Jacob uint64_t off;
1118d7b838eSMatt Jacob
1128d7b838eSMatt Jacob data_len = 0;
1138d7b838eSMatt Jacob status = SCSI_STATUS_OK;
1148d7b838eSMatt Jacob
1158d7b838eSMatt Jacob memset(&csio->sense_data, 0, sizeof (csio->sense_data));
1168d7b838eSMatt Jacob cdb = csio->cdb_io.cdb_bytes;
1178d7b838eSMatt Jacob
1188d7b838eSMatt Jacob if (csio->ccb_h.target_id >= MAX_TGT) {
1198d7b838eSMatt Jacob vhba_set_status(&csio->ccb_h, CAM_SEL_TIMEOUT);
1208d7b838eSMatt Jacob TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe);
1218d7b838eSMatt Jacob return;
1228d7b838eSMatt Jacob }
1238d7b838eSMatt Jacob if (vhbas->dead) {
1248d7b838eSMatt Jacob vhbas->dead = 0;
1258d7b838eSMatt Jacob vhba_set_status(&csio->ccb_h, CAM_SEL_TIMEOUT);
1268d7b838eSMatt Jacob TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe);
1278d7b838eSMatt Jacob return;
1288d7b838eSMatt Jacob }
1298d7b838eSMatt Jacob if (csio->ccb_h.target_lun >= MAX_LUN && cdb[0] != INQUIRY && cdb[0] != REPORT_LUNS && cdb[0] != REQUEST_SENSE) {
1308d7b838eSMatt Jacob vhba_fill_sense(csio, SSD_KEY_ILLEGAL_REQUEST, 0x25, 0x0);
1318d7b838eSMatt Jacob TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe);
1328d7b838eSMatt Jacob return;
1338d7b838eSMatt Jacob }
1348d7b838eSMatt Jacob
1358d7b838eSMatt Jacob switch (cdb[0]) {
1368d7b838eSMatt Jacob case MODE_SENSE:
1378d7b838eSMatt Jacob case MODE_SENSE_10:
1388d7b838eSMatt Jacob {
1398d7b838eSMatt Jacob unsigned int nbyte;
1408d7b838eSMatt Jacob uint8_t page = cdb[2] & SMS_PAGE_CODE;
1418d7b838eSMatt Jacob uint8_t pgctl = cdb[2] & SMS_PAGE_CTRL_MASK;
1428d7b838eSMatt Jacob
1438d7b838eSMatt Jacob switch (page) {
1448d7b838eSMatt Jacob case SMS_FORMAT_DEVICE_PAGE:
1458d7b838eSMatt Jacob case SMS_GEOMETRY_PAGE:
1468d7b838eSMatt Jacob case SMS_CACHE_PAGE:
1478d7b838eSMatt Jacob case SMS_CONTROL_MODE_PAGE:
1488d7b838eSMatt Jacob case SMS_ALL_PAGES_PAGE:
1498d7b838eSMatt Jacob break;
1508d7b838eSMatt Jacob default:
1518d7b838eSMatt Jacob vhba_fill_sense(csio, SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x0);
1528d7b838eSMatt Jacob TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe);
1538d7b838eSMatt Jacob return;
1548d7b838eSMatt Jacob }
1558d7b838eSMatt Jacob memset(junk, 0, sizeof (junk));
1568d7b838eSMatt Jacob if (cdb[1] & SMS_DBD) {
1578d7b838eSMatt Jacob ptr = &junk[4];
1588d7b838eSMatt Jacob } else {
1598d7b838eSMatt Jacob ptr = junk;
1608d7b838eSMatt Jacob ptr[3] = 8;
1618d7b838eSMatt Jacob ptr[4] = ((1 << DISK_SHIFT) >> 24) & 0xff;
1628d7b838eSMatt Jacob ptr[5] = ((1 << DISK_SHIFT) >> 16) & 0xff;
1638d7b838eSMatt Jacob ptr[6] = ((1 << DISK_SHIFT) >> 8) & 0xff;
1648d7b838eSMatt Jacob ptr[7] = ((1 << DISK_SHIFT)) & 0xff;
1658d7b838eSMatt Jacob
1668d7b838eSMatt Jacob ptr[8] = (DISK_NBLKS >> 24) & 0xff;
1678d7b838eSMatt Jacob ptr[9] = (DISK_NBLKS >> 16) & 0xff;
1688d7b838eSMatt Jacob ptr[10] = (DISK_NBLKS >> 8) & 0xff;
1698d7b838eSMatt Jacob ptr[11] = DISK_NBLKS & 0xff;
1708d7b838eSMatt Jacob ptr += 12;
1718d7b838eSMatt Jacob }
1728d7b838eSMatt Jacob
1738d7b838eSMatt Jacob if (page == SMS_ALL_PAGES_PAGE || page == SMS_FORMAT_DEVICE_PAGE) {
1748d7b838eSMatt Jacob ptr[0] = SMS_FORMAT_DEVICE_PAGE;
1758d7b838eSMatt Jacob ptr[1] = 24;
1768d7b838eSMatt Jacob if (pgctl != SMS_PAGE_CTRL_CHANGEABLE) {
1778d7b838eSMatt Jacob /* tracks per zone */
1788d7b838eSMatt Jacob /* ptr[2] = 0; */
1798d7b838eSMatt Jacob /* ptr[3] = 0; */
1808d7b838eSMatt Jacob /* alternate sectors per zone */
1818d7b838eSMatt Jacob /* ptr[4] = 0; */
1828d7b838eSMatt Jacob /* ptr[5] = 0; */
1838d7b838eSMatt Jacob /* alternate tracks per zone */
1848d7b838eSMatt Jacob /* ptr[6] = 0; */
1858d7b838eSMatt Jacob /* ptr[7] = 0; */
1868d7b838eSMatt Jacob /* alternate tracks per logical unit */
1878d7b838eSMatt Jacob /* ptr[8] = 0; */
1888d7b838eSMatt Jacob /* ptr[9] = 0; */
1898d7b838eSMatt Jacob /* sectors per track */
1908d7b838eSMatt Jacob ptr[10] = (PSEUDO_SPT >> 8) & 0xff;
1918d7b838eSMatt Jacob ptr[11] = PSEUDO_SPT & 0xff;
1928d7b838eSMatt Jacob /* data bytes per physical sector */
1938d7b838eSMatt Jacob ptr[12] = ((1 << DISK_SHIFT) >> 8) & 0xff;
1948d7b838eSMatt Jacob ptr[13] = (1 << DISK_SHIFT) & 0xff;
1958d7b838eSMatt Jacob /* interleave */
1968d7b838eSMatt Jacob /* ptr[14] = 0; */
1978d7b838eSMatt Jacob /* ptr[15] = 1; */
1988d7b838eSMatt Jacob /* track skew factor */
1998d7b838eSMatt Jacob /* ptr[16] = 0; */
2008d7b838eSMatt Jacob /* ptr[17] = 0; */
2018d7b838eSMatt Jacob /* cylinder skew factor */
2028d7b838eSMatt Jacob /* ptr[18] = 0; */
2038d7b838eSMatt Jacob /* ptr[19] = 0; */
2048d7b838eSMatt Jacob /* SSRC, HSEC, RMB, SURF */
2058d7b838eSMatt Jacob }
2068d7b838eSMatt Jacob ptr += 26;
2078d7b838eSMatt Jacob }
2088d7b838eSMatt Jacob
2098d7b838eSMatt Jacob if (page == SMS_ALL_PAGES_PAGE || page == SMS_GEOMETRY_PAGE) {
2108d7b838eSMatt Jacob ptr[0] = SMS_GEOMETRY_PAGE;
2118d7b838eSMatt Jacob ptr[1] = 24;
2128d7b838eSMatt Jacob if (pgctl != SMS_PAGE_CTRL_CHANGEABLE) {
2138d7b838eSMatt Jacob uint32_t cyl = (DISK_NBLKS + ((PSEUDO_SPC - 1))) / PSEUDO_SPC;
2148d7b838eSMatt Jacob /* number of cylinders */
2158d7b838eSMatt Jacob ptr[2] = (cyl >> 24) & 0xff;
2168d7b838eSMatt Jacob ptr[3] = (cyl >> 16) & 0xff;
2178d7b838eSMatt Jacob ptr[4] = cyl & 0xff;
2188d7b838eSMatt Jacob /* number of heads */
2198d7b838eSMatt Jacob ptr[5] = PSEUDO_HDS;
2208d7b838eSMatt Jacob /* starting cylinder- write precompensation */
2218d7b838eSMatt Jacob /* ptr[6] = 0; */
2228d7b838eSMatt Jacob /* ptr[7] = 0; */
2238d7b838eSMatt Jacob /* ptr[8] = 0; */
2248d7b838eSMatt Jacob /* starting cylinder- reduced write current */
2258d7b838eSMatt Jacob /* ptr[9] = 0; */
2268d7b838eSMatt Jacob /* ptr[10] = 0; */
2278d7b838eSMatt Jacob /* ptr[11] = 0; */
2288d7b838eSMatt Jacob /* drive step rate */
2298d7b838eSMatt Jacob /* ptr[12] = 0; */
2308d7b838eSMatt Jacob /* ptr[13] = 0; */
2318d7b838eSMatt Jacob /* landing zone cylinder */
2328d7b838eSMatt Jacob /* ptr[14] = 0; */
2338d7b838eSMatt Jacob /* ptr[15] = 0; */
2348d7b838eSMatt Jacob /* ptr[16] = 0; */
2358d7b838eSMatt Jacob /* RPL */
2368d7b838eSMatt Jacob /* ptr[17] = 0; */
2378d7b838eSMatt Jacob /* rotational offset */
2388d7b838eSMatt Jacob /* ptr[18] = 0; */
2398d7b838eSMatt Jacob /* medium rotation rate - 7200 RPM */
2408d7b838eSMatt Jacob ptr[20] = 0x1c;
2418d7b838eSMatt Jacob ptr[21] = 0x20;
2428d7b838eSMatt Jacob }
2438d7b838eSMatt Jacob ptr += 26;
2448d7b838eSMatt Jacob }
2458d7b838eSMatt Jacob
2468d7b838eSMatt Jacob if (page == SMS_ALL_PAGES_PAGE || page == SMS_CACHE_PAGE) {
2478d7b838eSMatt Jacob ptr[0] = SMS_CACHE_PAGE;
2488d7b838eSMatt Jacob ptr[1] = 18;
2498d7b838eSMatt Jacob ptr[2] = 1 << 2;
2508d7b838eSMatt Jacob ptr += 20;
2518d7b838eSMatt Jacob }
2528d7b838eSMatt Jacob
2538d7b838eSMatt Jacob if (page == SMS_ALL_PAGES_PAGE || page == SMS_CONTROL_MODE_PAGE) {
2548d7b838eSMatt Jacob ptr[0] = SMS_CONTROL_MODE_PAGE;
2558d7b838eSMatt Jacob ptr[1] = 10;
2568d7b838eSMatt Jacob if (pgctl != SMS_PAGE_CTRL_CHANGEABLE) {
2578d7b838eSMatt Jacob ptr[3] = 1 << 4; /* unrestricted reordering allowed */
2588d7b838eSMatt Jacob ptr[8] = 0x75; /* 30000 ms */
2598d7b838eSMatt Jacob ptr[9] = 0x30;
2608d7b838eSMatt Jacob }
2618d7b838eSMatt Jacob ptr += 12;
2628d7b838eSMatt Jacob }
2638d7b838eSMatt Jacob nbyte = (char *)ptr - &junk[0];
2648d7b838eSMatt Jacob ptr[0] = nbyte - 4;
2658d7b838eSMatt Jacob
2668d7b838eSMatt Jacob if (cdb[0] == MODE_SENSE) {
2678d7b838eSMatt Jacob data_len = min(cdb[4], csio->dxfer_len);
2688d7b838eSMatt Jacob } else {
2698d7b838eSMatt Jacob uint16_t tw = (cdb[7] << 8) | cdb[8];
2708d7b838eSMatt Jacob data_len = min(tw, csio->dxfer_len);
2718d7b838eSMatt Jacob }
2728d7b838eSMatt Jacob data_len = min(data_len, nbyte);
2738d7b838eSMatt Jacob if (data_len) {
2748d7b838eSMatt Jacob memcpy(csio->data_ptr, junk, data_len);
2758d7b838eSMatt Jacob }
2768d7b838eSMatt Jacob csio->resid = csio->dxfer_len - data_len;
2778d7b838eSMatt Jacob break;
2788d7b838eSMatt Jacob }
2798d7b838eSMatt Jacob case READ_6:
2808d7b838eSMatt Jacob case READ_10:
2818d7b838eSMatt Jacob case READ_12:
2828d7b838eSMatt Jacob case READ_16:
2838d7b838eSMatt Jacob case WRITE_6:
2848d7b838eSMatt Jacob case WRITE_10:
2858d7b838eSMatt Jacob case WRITE_12:
2868d7b838eSMatt Jacob case WRITE_16:
2878d7b838eSMatt Jacob if (vhba_rwparm(cdb, &off, &data_len, DISK_NBLKS, DISK_SHIFT)) {
2888d7b838eSMatt Jacob vhba_fill_sense(csio, SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x0);
2898d7b838eSMatt Jacob break;
2908d7b838eSMatt Jacob }
2918d7b838eSMatt Jacob if (data_len) {
2928d7b838eSMatt Jacob if ((cdb[0] & 0xf) == 8) {
2938d7b838eSMatt Jacob memcpy(csio->data_ptr, &vhbas->disk[off], data_len);
2948d7b838eSMatt Jacob } else {
2958d7b838eSMatt Jacob memcpy(&vhbas->disk[off], csio->data_ptr, data_len);
2968d7b838eSMatt Jacob }
2978d7b838eSMatt Jacob csio->resid = csio->dxfer_len - data_len;
2988d7b838eSMatt Jacob } else {
2998d7b838eSMatt Jacob csio->resid = csio->dxfer_len;
3008d7b838eSMatt Jacob }
3018d7b838eSMatt Jacob break;
3028d7b838eSMatt Jacob
3038d7b838eSMatt Jacob case READ_CAPACITY:
3048d7b838eSMatt Jacob if (cdb[2] || cdb[3] || cdb[4] || cdb[5]) {
3058d7b838eSMatt Jacob vhba_fill_sense(csio, SSD_KEY_UNIT_ATTENTION, 0x24, 0x0);
3068d7b838eSMatt Jacob break;
3078d7b838eSMatt Jacob }
3088d7b838eSMatt Jacob if (cdb[8] & 0x1) { /* PMI */
3098d7b838eSMatt Jacob csio->data_ptr[0] = 0xff;
3108d7b838eSMatt Jacob csio->data_ptr[1] = 0xff;
3118d7b838eSMatt Jacob csio->data_ptr[2] = 0xff;
3128d7b838eSMatt Jacob csio->data_ptr[3] = 0xff;
3138d7b838eSMatt Jacob } else {
3148d7b838eSMatt Jacob uint64_t last_blk = DISK_NBLKS - 1;
3158d7b838eSMatt Jacob if (last_blk < 0xffffffffULL) {
3168d7b838eSMatt Jacob csio->data_ptr[0] = (last_blk >> 24) & 0xff;
3178d7b838eSMatt Jacob csio->data_ptr[1] = (last_blk >> 16) & 0xff;
3188d7b838eSMatt Jacob csio->data_ptr[2] = (last_blk >> 8) & 0xff;
3198d7b838eSMatt Jacob csio->data_ptr[3] = (last_blk) & 0xff;
3208d7b838eSMatt Jacob } else {
3218d7b838eSMatt Jacob csio->data_ptr[0] = 0xff;
3228d7b838eSMatt Jacob csio->data_ptr[1] = 0xff;
3238d7b838eSMatt Jacob csio->data_ptr[2] = 0xff;
3248d7b838eSMatt Jacob csio->data_ptr[3] = 0xff;
3258d7b838eSMatt Jacob }
3268d7b838eSMatt Jacob }
3278d7b838eSMatt Jacob csio->data_ptr[4] = ((1 << DISK_SHIFT) >> 24) & 0xff;
3288d7b838eSMatt Jacob csio->data_ptr[5] = ((1 << DISK_SHIFT) >> 16) & 0xff;
3298d7b838eSMatt Jacob csio->data_ptr[6] = ((1 << DISK_SHIFT) >> 8) & 0xff;
3308d7b838eSMatt Jacob csio->data_ptr[7] = ((1 << DISK_SHIFT)) & 0xff;
3318d7b838eSMatt Jacob break;
3328d7b838eSMatt Jacob default:
3338d7b838eSMatt Jacob vhba_default_cmd(csio, MAX_LUN, NULL);
3348d7b838eSMatt Jacob break;
3358d7b838eSMatt Jacob }
3368d7b838eSMatt Jacob if (csio->scsi_status != SCSI_STATUS_OK) {
3378d7b838eSMatt Jacob camstatus = CAM_SCSI_STATUS_ERROR;
3388d7b838eSMatt Jacob if (csio->scsi_status == SCSI_STATUS_CHECK_COND) {
3398d7b838eSMatt Jacob camstatus |= CAM_AUTOSNS_VALID;
3408d7b838eSMatt Jacob }
3418d7b838eSMatt Jacob } else {
3428d7b838eSMatt Jacob csio->scsi_status = SCSI_STATUS_OK;
3438d7b838eSMatt Jacob camstatus = CAM_REQ_CMP;
3448d7b838eSMatt Jacob }
3458d7b838eSMatt Jacob vhba_set_status(&csio->ccb_h, camstatus);
3468d7b838eSMatt Jacob TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe);
3478d7b838eSMatt Jacob }
3488d7b838eSMatt Jacob DEV_MODULE(vhba_faulty, vhba_modprobe, NULL);
349