Deleted Added
full compact
scsi_ctl.c (312844) scsi_ctl.c (313364)
1/*-
2 * Copyright (c) 2008, 2009 Silicon Graphics International Corp.
3 * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 23 unchanged lines hidden (view full) ---

32 */
33/*
34 * Peripheral driver interface between CAM and CTL (CAM Target Layer).
35 *
36 * Author: Ken Merry <ken@FreeBSD.org>
37 */
38
39#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008, 2009 Silicon Graphics International Corp.
3 * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 23 unchanged lines hidden (view full) ---

32 */
33/*
34 * Peripheral driver interface between CAM and CTL (CAM Target Layer).
35 *
36 * Author: Ken Merry <ken@FreeBSD.org>
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/scsi_ctl.c 312844 2017-01-26 21:06:59Z mav $");
40__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/scsi_ctl.c 313364 2017-02-07 01:42:13Z mav $");
41
42#include <sys/param.h>
43#include <sys/queue.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/lock.h>
47#include <sys/mutex.h>
48#include <sys/condvar.h>

--- 667 unchanged lines hidden (view full) ---

716 *flags |= CAM_DIR_IN;
717 else
718 *flags |= CAM_DIR_OUT;
719
720 *flags &= ~CAM_DATA_MASK;
721 idx = cmd_info->cur_transfer_index;
722 off = cmd_info->cur_transfer_off;
723 cmd_info->flags &= ~CTLFE_CMD_PIECEWISE;
41
42#include <sys/param.h>
43#include <sys/queue.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/lock.h>
47#include <sys/mutex.h>
48#include <sys/condvar.h>

--- 667 unchanged lines hidden (view full) ---

716 *flags |= CAM_DIR_IN;
717 else
718 *flags |= CAM_DIR_OUT;
719
720 *flags &= ~CAM_DATA_MASK;
721 idx = cmd_info->cur_transfer_index;
722 off = cmd_info->cur_transfer_off;
723 cmd_info->flags &= ~CTLFE_CMD_PIECEWISE;
724 if (io->scsiio.kern_sg_entries == 0) {
725 /* No S/G list. */
724 if (io->scsiio.kern_sg_entries == 0) { /* No S/G list. */
725
726 /* One time shift for SRR offset. */
727 off += io->scsiio.ext_data_filled;
728 io->scsiio.ext_data_filled = 0;
729
726 *data_ptr = io->scsiio.kern_data_ptr + off;
727 if (io->scsiio.kern_data_len - off <= bus_softc->maxio) {
728 *dxfer_len = io->scsiio.kern_data_len - off;
729 } else {
730 *dxfer_len = bus_softc->maxio;
730 *data_ptr = io->scsiio.kern_data_ptr + off;
731 if (io->scsiio.kern_data_len - off <= bus_softc->maxio) {
732 *dxfer_len = io->scsiio.kern_data_len - off;
733 } else {
734 *dxfer_len = bus_softc->maxio;
731 cmd_info->cur_transfer_index = -1;
732 cmd_info->cur_transfer_off = bus_softc->maxio;
735 cmd_info->cur_transfer_off += bus_softc->maxio;
733 cmd_info->flags |= CTLFE_CMD_PIECEWISE;
734 }
735 *sglist_cnt = 0;
736
737 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
738 *flags |= CAM_DATA_PADDR;
739 else
740 *flags |= CAM_DATA_VADDR;
736 cmd_info->flags |= CTLFE_CMD_PIECEWISE;
737 }
738 *sglist_cnt = 0;
739
740 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
741 *flags |= CAM_DATA_PADDR;
742 else
743 *flags |= CAM_DATA_VADDR;
741 } else {
742 /* S/G list with physical or virtual pointers. */
744 } else { /* S/G list with physical or virtual pointers. */
743 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
745 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
746
747 /* One time shift for SRR offset. */
748 while (io->scsiio.ext_data_filled >= ctl_sglist[idx].len - off) {
749 io->scsiio.ext_data_filled -= ctl_sglist[idx].len - off;
750 idx++;
751 off = 0;
752 }
753 off += io->scsiio.ext_data_filled;
754 io->scsiio.ext_data_filled = 0;
755
744 cam_sglist = cmd_info->cam_sglist;
745 *dxfer_len = 0;
746 for (i = 0; i < io->scsiio.kern_sg_entries - idx; i++) {
747 cam_sglist[i].ds_addr = (bus_addr_t)ctl_sglist[i + idx].addr + off;
748 if (ctl_sglist[i + idx].len - off <= bus_softc->maxio - *dxfer_len) {
749 cam_sglist[i].ds_len = ctl_sglist[idx + i].len - off;
750 *dxfer_len += cam_sglist[i].ds_len;
751 } else {

--- 61 unchanged lines hidden (view full) ---

813 cmd_info->cur_transfer_index = 0;
814 cmd_info->cur_transfer_off = 0;
815 cmd_info->flags = 0;
816
817 if (io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) {
818 /*
819 * Datamove call, we need to setup the S/G list.
820 */
756 cam_sglist = cmd_info->cam_sglist;
757 *dxfer_len = 0;
758 for (i = 0; i < io->scsiio.kern_sg_entries - idx; i++) {
759 cam_sglist[i].ds_addr = (bus_addr_t)ctl_sglist[i + idx].addr + off;
760 if (ctl_sglist[i + idx].len - off <= bus_softc->maxio - *dxfer_len) {
761 cam_sglist[i].ds_len = ctl_sglist[idx + i].len - off;
762 *dxfer_len += cam_sglist[i].ds_len;
763 } else {

--- 61 unchanged lines hidden (view full) ---

825 cmd_info->cur_transfer_index = 0;
826 cmd_info->cur_transfer_off = 0;
827 cmd_info->flags = 0;
828
829 if (io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) {
830 /*
831 * Datamove call, we need to setup the S/G list.
832 */
821 scsi_status = 0;
822 csio->cdb_len = atio->cdb_len;
823 ctlfedata(softc, io, &flags, &data_ptr, &dxfer_len,
824 &csio->sglist_cnt);
833 ctlfedata(softc, io, &flags, &data_ptr, &dxfer_len,
834 &csio->sglist_cnt);
825 io->scsiio.ext_data_filled += dxfer_len;
826 if (io->scsiio.ext_data_filled > io->scsiio.kern_total_len) {
827 xpt_print(periph->path, "%s: tag 0x%04x "
828 "fill len %u > total %u\n",
829 __func__, io->scsiio.tag_num,
830 io->scsiio.ext_data_filled,
831 io->scsiio.kern_total_len);
832 }
833 } else {
834 /*
835 * We're done, send status back.
836 */
837 if ((io->io_hdr.flags & CTL_FLAG_ABORT) &&
838 (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) {
839 io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED;
840

--- 45 unchanged lines hidden (view full) ---

886 */
887 if (!TAILQ_EMPTY(&softc->work_queue))
888 xpt_schedule(periph, /*priority*/ 1);
889 return;
890 }
891 data_ptr = NULL;
892 dxfer_len = 0;
893 csio->sglist_cnt = 0;
835 } else {
836 /*
837 * We're done, send status back.
838 */
839 if ((io->io_hdr.flags & CTL_FLAG_ABORT) &&
840 (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) {
841 io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED;
842

--- 45 unchanged lines hidden (view full) ---

888 */
889 if (!TAILQ_EMPTY(&softc->work_queue))
890 xpt_schedule(periph, /*priority*/ 1);
891 return;
892 }
893 data_ptr = NULL;
894 dxfer_len = 0;
895 csio->sglist_cnt = 0;
894 scsi_status = 0;
895 }
896 }
897 scsi_status = 0;
896 if ((io->io_hdr.flags & CTL_FLAG_STATUS_QUEUED) &&
897 (cmd_info->flags & CTLFE_CMD_PIECEWISE) == 0 &&
898 ((io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) == 0 ||
899 io->io_hdr.status == CTL_SUCCESS)) {
900 flags |= CAM_SEND_STATUS;
901 scsi_status = io->scsiio.scsi_status;
902 csio->sense_len = io->scsiio.sense_len;
903#ifdef CTLFEDEBUG

--- 337 unchanged lines hidden (view full) ---

1241 srr = 1;
1242 srr_off =
1243 (done_ccb->csio.msg_ptr[3] << 24)
1244 | (done_ccb->csio.msg_ptr[4] << 16)
1245 | (done_ccb->csio.msg_ptr[5] << 8)
1246 | (done_ccb->csio.msg_ptr[6]);
1247 }
1248
898 if ((io->io_hdr.flags & CTL_FLAG_STATUS_QUEUED) &&
899 (cmd_info->flags & CTLFE_CMD_PIECEWISE) == 0 &&
900 ((io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) == 0 ||
901 io->io_hdr.status == CTL_SUCCESS)) {
902 flags |= CAM_SEND_STATUS;
903 scsi_status = io->scsiio.scsi_status;
904 csio->sense_len = io->scsiio.sense_len;
905#ifdef CTLFEDEBUG

--- 337 unchanged lines hidden (view full) ---

1243 srr = 1;
1244 srr_off =
1245 (done_ccb->csio.msg_ptr[3] << 24)
1246 | (done_ccb->csio.msg_ptr[4] << 16)
1247 | (done_ccb->csio.msg_ptr[5] << 8)
1248 | (done_ccb->csio.msg_ptr[6]);
1249 }
1250
1251 /*
1252 * If we have an SRR and we're still sending data, we
1253 * should be able to adjust offsets and cycle again.
1254 * It is possible only if offset is from this datamove.
1255 */
1256 if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) &&
1257 srr_off >= io->scsiio.kern_rel_offset &&
1258 srr_off < io->scsiio.kern_rel_offset +
1259 io->scsiio.kern_data_len) {
1260 io->scsiio.kern_data_resid =
1261 io->scsiio.kern_rel_offset +
1262 io->scsiio.kern_data_len - srr_off;
1263 io->scsiio.ext_data_filled = srr_off;
1264 io->scsiio.io_hdr.status = CTL_STATUS_NONE;
1265 io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED;
1266 softc->ccbs_freed++;
1267 xpt_release_ccb(done_ccb);
1268 TAILQ_INSERT_HEAD(&softc->work_queue, &atio->ccb_h,
1269 periph_links.tqe);
1270 xpt_schedule(periph, /*priority*/ 1);
1271 break;
1272 }
1273
1274 /*
1275 * If status was being sent, the back end data is now history.
1276 * Hack it up and resubmit a new command with the CDB adjusted.
1277 * If the SIM does the right thing, all of the resid math
1278 * should work.
1279 */
1249 if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) == 0) {
1280 if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) == 0) {
1250 /*
1251 * If status was being sent, the back end data is now
1252 * history. Hack it up and resubmit a new command with
1253 * the CDB adjusted. If the SIM does the right thing,
1254 * all of the resid math should work.
1255 */
1256 softc->ccbs_freed++;
1257 xpt_release_ccb(done_ccb);
1258 if (ctlfe_adjust_cdb(atio, srr_off) == 0) {
1259 done_ccb = (union ccb *)atio;
1260 goto resubmit;
1261 }
1262 /*
1263 * Fall through to doom....
1264 */
1281 softc->ccbs_freed++;
1282 xpt_release_ccb(done_ccb);
1283 if (ctlfe_adjust_cdb(atio, srr_off) == 0) {
1284 done_ccb = (union ccb *)atio;
1285 goto resubmit;
1286 }
1287 /*
1288 * Fall through to doom....
1289 */
1265 } else if (srr) {
1266 /*
1267 * If we have an srr and we're still sending data, we
1268 * should be able to adjust offsets and cycle again.
1269 */
1270 io->scsiio.kern_rel_offset =
1271 io->scsiio.ext_data_filled = srr_off;
1272 io->scsiio.ext_data_len = io->scsiio.kern_total_len -
1273 io->scsiio.kern_rel_offset;
1274 softc->ccbs_freed++;
1275 io->scsiio.io_hdr.status = CTL_STATUS_NONE;
1276 xpt_release_ccb(done_ccb);
1277 TAILQ_INSERT_HEAD(&softc->work_queue, &atio->ccb_h,
1278 periph_links.tqe);
1279 xpt_schedule(periph, /*priority*/ 1);
1280 break;
1281 }
1282
1283 if ((done_ccb->ccb_h.flags & CAM_SEND_STATUS) &&
1284 (done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1285 io->io_hdr.flags |= CTL_FLAG_STATUS_SENT;
1286
1287 /*
1288 * If we were sending status back to the initiator, free up

--- 26 unchanged lines hidden (view full) ---

1315 struct ctlfe_cmd_info *cmd_info;
1316 struct ccb_scsiio *csio;
1317
1318 csio = &done_ccb->csio;
1319 cmd_info = PRIV_INFO(io);
1320
1321 io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG;
1322
1290 }
1291
1292 if ((done_ccb->ccb_h.flags & CAM_SEND_STATUS) &&
1293 (done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1294 io->io_hdr.flags |= CTL_FLAG_STATUS_SENT;
1295
1296 /*
1297 * If we were sending status back to the initiator, free up

--- 26 unchanged lines hidden (view full) ---

1324 struct ctlfe_cmd_info *cmd_info;
1325 struct ccb_scsiio *csio;
1326
1327 csio = &done_ccb->csio;
1328 cmd_info = PRIV_INFO(io);
1329
1330 io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG;
1331
1323 io->scsiio.ext_data_len += csio->dxfer_len;
1324 if (io->scsiio.ext_data_len >
1325 io->scsiio.kern_total_len) {
1326 xpt_print(periph->path, "%s: tag 0x%04x "
1327 "done len %u > total %u sent %u\n",
1328 __func__, io->scsiio.tag_num,
1329 io->scsiio.ext_data_len,
1330 io->scsiio.kern_total_len,
1331 io->scsiio.ext_data_filled);
1332 }
1333 /*
1334 * Translate CAM status to CTL status. Success
1335 * does not change the overall, ctl_io status. In
1336 * that case we just set port_status to 0. If we
1337 * have a failure, though, set a data phase error
1338 * for the overall ctl_io.
1339 */
1340 switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) {
1341 case CAM_REQ_CMP:
1332 /*
1333 * Translate CAM status to CTL status. Success
1334 * does not change the overall, ctl_io status. In
1335 * that case we just set port_status to 0. If we
1336 * have a failure, though, set a data phase error
1337 * for the overall ctl_io.
1338 */
1339 switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) {
1340 case CAM_REQ_CMP:
1341 io->scsiio.kern_data_resid -= csio->dxfer_len;
1342 io->io_hdr.port_status = 0;
1343 break;
1344 default:
1345 /*
1346 * XXX KDM we probably need to figure out a
1347 * standard set of errors that the SIM
1348 * drivers should return in the event of a
1349 * data transfer failure. A data phase

--- 13 unchanged lines hidden (view full) ---

1363 /*
1364 * If we had to break this S/G list into multiple
1365 * pieces, figure out where we are in the list, and
1366 * continue sending pieces if necessary.
1367 */
1368 if ((cmd_info->flags & CTLFE_CMD_PIECEWISE)
1369 && (io->io_hdr.port_status == 0)) {
1370 ccb_flags flags;
1342 io->io_hdr.port_status = 0;
1343 break;
1344 default:
1345 /*
1346 * XXX KDM we probably need to figure out a
1347 * standard set of errors that the SIM
1348 * drivers should return in the event of a
1349 * data transfer failure. A data phase

--- 13 unchanged lines hidden (view full) ---

1363 /*
1364 * If we had to break this S/G list into multiple
1365 * pieces, figure out where we are in the list, and
1366 * continue sending pieces if necessary.
1367 */
1368 if ((cmd_info->flags & CTLFE_CMD_PIECEWISE)
1369 && (io->io_hdr.port_status == 0)) {
1370 ccb_flags flags;
1371 uint8_t scsi_status;
1372 uint8_t *data_ptr;
1373 uint32_t dxfer_len;
1374
1375 flags = atio->ccb_h.flags &
1376 (CAM_DIS_DISCONNECT|
1377 CAM_TAG_ACTION_VALID);
1378
1379 ctlfedata(softc, io, &flags, &data_ptr,
1380 &dxfer_len, &csio->sglist_cnt);
1381
1371 uint8_t *data_ptr;
1372 uint32_t dxfer_len;
1373
1374 flags = atio->ccb_h.flags &
1375 (CAM_DIS_DISCONNECT|
1376 CAM_TAG_ACTION_VALID);
1377
1378 ctlfedata(softc, io, &flags, &data_ptr,
1379 &dxfer_len, &csio->sglist_cnt);
1380
1382 scsi_status = 0;
1383
1384 if (((flags & CAM_SEND_STATUS) == 0)
1385 && (dxfer_len == 0)) {
1386 printf("%s: tag %04x no status or "
1387 "len cdb = %02x\n", __func__,
1388 atio->tag_id,
1389 atio_cdb_ptr(atio)[0]);
1390 printf("%s: tag %04x io status %#x\n",
1391 __func__, atio->tag_id,
1392 io->io_hdr.status);
1393 }
1394
1395 cam_fill_ctio(csio,
1396 /*retries*/ 2,
1397 ctlfedone,
1398 flags,
1399 (flags & CAM_TAG_ACTION_VALID) ?
1400 MSG_SIMPLE_Q_TAG : 0,
1401 atio->tag_id,
1402 atio->init_id,
1381 if (((flags & CAM_SEND_STATUS) == 0)
1382 && (dxfer_len == 0)) {
1383 printf("%s: tag %04x no status or "
1384 "len cdb = %02x\n", __func__,
1385 atio->tag_id,
1386 atio_cdb_ptr(atio)[0]);
1387 printf("%s: tag %04x io status %#x\n",
1388 __func__, atio->tag_id,
1389 io->io_hdr.status);
1390 }
1391
1392 cam_fill_ctio(csio,
1393 /*retries*/ 2,
1394 ctlfedone,
1395 flags,
1396 (flags & CAM_TAG_ACTION_VALID) ?
1397 MSG_SIMPLE_Q_TAG : 0,
1398 atio->tag_id,
1399 atio->init_id,
1403 scsi_status,
1400 0,
1404 /*data_ptr*/ data_ptr,
1405 /*dxfer_len*/ dxfer_len,
1406 /*timeout*/ 5 * 1000);
1407
1408 csio->ccb_h.flags |= CAM_UNLOCKED;
1409 csio->resid = 0;
1410 csio->ccb_h.ccb_atio = atio;
1411 io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;

--- 586 unchanged lines hidden (view full) ---

1998{
1999 union ccb *ccb;
2000 struct cam_periph *periph;
2001 struct ctlfe_lun_softc *softc;
2002
2003 KASSERT(io->io_hdr.io_type == CTL_IO_SCSI,
2004 ("Unexpected io_type (%d) in ctlfe_datamove", io->io_hdr.io_type));
2005
1401 /*data_ptr*/ data_ptr,
1402 /*dxfer_len*/ dxfer_len,
1403 /*timeout*/ 5 * 1000);
1404
1405 csio->ccb_h.flags |= CAM_UNLOCKED;
1406 csio->resid = 0;
1407 csio->ccb_h.ccb_atio = atio;
1408 io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;

--- 586 unchanged lines hidden (view full) ---

1995{
1996 union ccb *ccb;
1997 struct cam_periph *periph;
1998 struct ctlfe_lun_softc *softc;
1999
2000 KASSERT(io->io_hdr.io_type == CTL_IO_SCSI,
2001 ("Unexpected io_type (%d) in ctlfe_datamove", io->io_hdr.io_type));
2002
2003 io->scsiio.ext_data_filled = 0;
2006 ccb = PRIV_CCB(io);
2007 periph = xpt_path_periph(ccb->ccb_h.path);
2008 cam_periph_lock(periph);
2009 softc = (struct ctlfe_lun_softc *)periph->softc;
2010 io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED;
2011 if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
2012 io->io_hdr.flags |= CTL_FLAG_STATUS_QUEUED;
2013 TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h,

--- 89 unchanged lines hidden ---
2004 ccb = PRIV_CCB(io);
2005 periph = xpt_path_periph(ccb->ccb_h.path);
2006 cam_periph_lock(periph);
2007 softc = (struct ctlfe_lun_softc *)periph->softc;
2008 io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED;
2009 if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
2010 io->io_hdr.flags |= CTL_FLAG_STATUS_QUEUED;
2011 TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h,

--- 89 unchanged lines hidden ---