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 --- |