svn commit: r254416 - head/sys/cam/scsi

Kenneth D. Merry ken at FreeBSD.org
Fri Aug 16 16:14:33 UTC 2013


Author: ken
Date: Fri Aug 16 16:14:32 2013
New Revision: 254416
URL: http://svnweb.freebsd.org/changeset/base/254416

Log:
  Add unmapped I/O and larger I/O support to the sa(4) driver.
  
  We now pay attention to the maxio field in the XPT_PATH_INQ CCB,
  and if it is set, propagate it up to physio via the si_iosize_max
  field in the cdev structure.
  
  We also now pay attention to the PIM_UNMAPPED capability bit in the
  XPT_PATH_INQ CCB, and set the new SI_UNMAPPED cdev flag when the
  underlying SIM supports unmapped I/O.
  
  scsi_sa.c:	Add unmapped I/O support and propagate the SIM's
  		maximum I/O size up.
  
  		Adjust scsi_tape_read_write() in the same way that
  		scsi_read_write() was changed to support unmapped
  		I/O.  We overload the readop parameter with bits
  		that tell us whether it's an unmapped I/O, and we
  		need to set the CAM_DATA_BIO CCB flag.  This change
  		should be backwards compatible in source and
  		binary forms.
  
  MFC after:	1 week
  Sponsored by:	Spectra Logic

Modified:
  head/sys/cam/scsi/scsi_sa.c

Modified: head/sys/cam/scsi/scsi_sa.c
==============================================================================
--- head/sys/cam/scsi/scsi_sa.c	Fri Aug 16 14:22:20 2013	(r254415)
+++ head/sys/cam/scsi/scsi_sa.c	Fri Aug 16 16:14:32 2013	(r254416)
@@ -212,6 +212,7 @@ struct sa_softc {
 	sa_state	state;
 	sa_flags	flags;
 	sa_quirks	quirks;
+	u_int		si_flags;
 	struct		bio_queue_head bio_queue;
 	int		queue_count;
 	struct		devstat *device_stats;
@@ -221,6 +222,7 @@ struct sa_softc {
 	int		blk_shift;
 	u_int32_t	max_blk;
 	u_int32_t	min_blk;
+	u_int32_t	maxio;
 	u_int32_t	comp_algorithm;
 	u_int32_t	saved_comp_algorithm;
 	u_int32_t	media_blksize;
@@ -447,7 +449,7 @@ static struct cdevsw sa_cdevsw = {
 	.d_ioctl =	saioctl,
 	.d_strategy =	sastrategy,
 	.d_name =	"sa",
-	.d_flags =	D_TAPE | D_NEEDGIANT,
+	.d_flags =	D_TAPE,
 };
 
 static int
@@ -1506,10 +1508,29 @@ saregister(struct cam_periph *periph, vo
 	    DEVSTAT_BS_UNAVAILABLE, SID_TYPE(&cgd->inq_data) |
 	    XPORT_DEVSTAT_TYPE(cpi.transport), DEVSTAT_PRIORITY_TAPE);
 
+	/*
+	 * If maxio isn't set, we fall back to DFLTPHYS.  If it is set, we
+	 * take it whether or not it's larger than MAXPHYS.  physio will
+	 * break it down into pieces small enough to fit in a buffer.
+	 */
+	if (cpi.maxio == 0)
+		softc->maxio = DFLTPHYS;
+	else
+		softc->maxio = cpi.maxio;
+
+	/*
+	 * If the SIM supports unmapped I/O, let physio know that we can
+	 * handle unmapped buffers.
+	 */
+	if (cpi.hba_misc & PIM_UNMAPPED)
+		softc->si_flags = SI_UNMAPPED;
+
 	softc->devs.ctl_dev = make_dev(&sa_cdevsw, SAMINOR(SA_CTLDEV,
 	    0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR,
 	    0660, "%s%d.ctl", periph->periph_name, periph->unit_number);
 	softc->devs.ctl_dev->si_drv1 = periph;
+	softc->devs.ctl_dev->si_iosize_max = softc->maxio;
+	softc->devs.ctl_dev->si_flags |= softc->si_flags;
 
 	for (i = 0; i < SA_NUM_MODES; i++) {
 
@@ -1518,18 +1539,24 @@ saregister(struct cam_periph *periph, vo
 		    UID_ROOT, GID_OPERATOR, 0660, "%s%d.%d",
 		    periph->periph_name, periph->unit_number, i);
 		softc->devs.mode_devs[i].r_dev->si_drv1 = periph;
+		softc->devs.mode_devs[i].r_dev->si_iosize_max = softc->maxio;
+		softc->devs.mode_devs[i].r_dev->si_flags |= softc->si_flags;
 
 		softc->devs.mode_devs[i].nr_dev = make_dev(&sa_cdevsw,
 		    SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_NR),
 		    UID_ROOT, GID_OPERATOR, 0660, "n%s%d.%d",
 		    periph->periph_name, periph->unit_number, i);
 		softc->devs.mode_devs[i].nr_dev->si_drv1 = periph;
+		softc->devs.mode_devs[i].nr_dev->si_iosize_max = softc->maxio;
+		softc->devs.mode_devs[i].nr_dev->si_flags |= softc->si_flags;
 
 		softc->devs.mode_devs[i].er_dev = make_dev(&sa_cdevsw,
 		    SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_ER),
 		    UID_ROOT, GID_OPERATOR, 0660, "e%s%d.%d",
 		    periph->periph_name, periph->unit_number, i);
 		softc->devs.mode_devs[i].er_dev->si_drv1 = periph;
+		softc->devs.mode_devs[i].er_dev->si_iosize_max = softc->maxio;
+		softc->devs.mode_devs[i].er_dev->si_flags |= softc->si_flags;
 
 		/*
 		 * Make the (well known) aliases for the first mode.
@@ -1540,12 +1567,20 @@ saregister(struct cam_periph *periph, vo
 			alias = make_dev_alias(softc->devs.mode_devs[i].r_dev,
 			   "%s%d", periph->periph_name, periph->unit_number);
 			alias->si_drv1 = periph;
+			alias->si_iosize_max = softc->maxio;
+			alias->si_flags |= softc->si_flags;
+
 			alias = make_dev_alias(softc->devs.mode_devs[i].nr_dev,
 			    "n%s%d", periph->periph_name, periph->unit_number);
 			alias->si_drv1 = periph;
+			alias->si_iosize_max = softc->maxio;
+			alias->si_flags |= softc->si_flags;
+
 			alias = make_dev_alias(softc->devs.mode_devs[i].er_dev,
 			    "e%s%d", periph->periph_name, periph->unit_number);
 			alias->si_drv1 = periph;
+			alias->si_iosize_max = softc->maxio;
+			alias->si_flags |= softc->si_flags;
 		}
 	}
 	cam_periph_lock(periph);
@@ -1694,9 +1729,13 @@ again:
 			softc->dsreg = (bp->bio_cmd == BIO_READ)?
 			    MTIO_DSREG_RD : MTIO_DSREG_WR;
 			scsi_sa_read_write(&start_ccb->csio, 0, sadone,
-			    MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ),
-			    FALSE, (softc->flags & SA_FLAG_FIXED) != 0,
-			    length, bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE,
+			    MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ ? 
+			    SCSI_RW_READ : SCSI_RW_WRITE) |
+			    ((bp->bio_flags & BIO_UNMAPPED) != 0 ?
+			    SCSI_RW_BIO : 0), FALSE,
+			    (softc->flags & SA_FLAG_FIXED) != 0, length,
+			    (bp->bio_flags & BIO_UNMAPPED) != 0 ? (void *)bp :
+			    bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE,
 			    IO_TIMEOUT);
 			start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
 			Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO);
@@ -3431,18 +3470,22 @@ scsi_sa_read_write(struct ccb_scsiio *cs
 		   u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout)
 {
 	struct scsi_sa_rw *scsi_cmd;
+	int read;
+
+	read = (readop & SCSI_RW_DIRMASK) == SCSI_RW_READ;
 
 	scsi_cmd = (struct scsi_sa_rw *)&csio->cdb_io.cdb_bytes;
-	scsi_cmd->opcode = readop ? SA_READ : SA_WRITE;
+	scsi_cmd->opcode = read ? SA_READ : SA_WRITE;
 	scsi_cmd->sli_fixed = 0;
-	if (sli && readop)
+	if (sli && read)
 		scsi_cmd->sli_fixed |= SAR_SLI;
 	if (fixed)
 		scsi_cmd->sli_fixed |= SARW_FIXED;
 	scsi_ulto3b(length, scsi_cmd->length);
 	scsi_cmd->control = 0;
 
-	cam_fill_csio(csio, retries, cbfcnp, readop ? CAM_DIR_IN : CAM_DIR_OUT,
+	cam_fill_csio(csio, retries, cbfcnp, (read ? CAM_DIR_IN : CAM_DIR_OUT) |
+	    ((readop & SCSI_RW_BIO) != 0 ? CAM_DATA_BIO : 0),
 	    tag_action, data_ptr, dxfer_len, sense_len,
 	    sizeof(*scsi_cmd), timeout);
 }


More information about the svn-src-all mailing list