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

Scott Long scottl at FreeBSD.org
Wed Dec 2 16:08:33 UTC 2009


Author: scottl
Date: Wed Dec  2 16:08:33 2009
New Revision: 200036
URL: http://svn.freebsd.org/changeset/base/200036

Log:
  Fix several cases where the periph lock was held over malloc.
  
  Submitted by:	Jaakko Heinonen

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

Modified: head/sys/cam/scsi/scsi_cd.c
==============================================================================
--- head/sys/cam/scsi/scsi_cd.c	Wed Dec  2 15:56:18 2009	(r200035)
+++ head/sys/cam/scsi/scsi_cd.c	Wed Dec  2 16:08:33 2009	(r200036)
@@ -2673,12 +2673,10 @@ cdioctl(struct disk *dp, u_long cmd, voi
 
 		authinfo = (struct dvd_authinfo *)addr;
 
-		cam_periph_lock(periph);
 		if (cmd == DVDIOCREPORTKEY)
 			error = cdreportkey(periph, authinfo);
 		else
 			error = cdsendkey(periph, authinfo);
-		cam_periph_unlock(periph);
 		break;
 		}
 	case DVDIOCREADSTRUCTURE: {
@@ -2686,9 +2684,7 @@ cdioctl(struct disk *dp, u_long cmd, voi
 
 		dvdstruct = (struct dvd_struct *)addr;
 
-		cam_periph_lock(periph);
 		error = cdreaddvdstructure(periph, dvdstruct);
-		cam_periph_unlock(periph);
 
 		break;
 	}
@@ -3732,8 +3728,6 @@ cdreportkey(struct cam_periph *periph, s
 	databuf = NULL;
 	lba = 0;
 
-	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
-
 	switch (authinfo->format) {
 	case DVD_REPORT_AGID:
 		length = sizeof(struct scsi_report_key_data_agid);
@@ -3759,9 +3753,7 @@ cdreportkey(struct cam_periph *periph, s
 		length = 0;
 		break;
 	default:
-		error = EINVAL;
-		goto bailout;
-		break; /* NOTREACHED */
+		return (EINVAL);
 	}
 
 	if (length != 0) {
@@ -3769,6 +3761,8 @@ cdreportkey(struct cam_periph *periph, s
 	} else
 		databuf = NULL;
 
+	cam_periph_lock(periph);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
 
 	scsi_report_key(&ccb->csio,
 			/* retries */ 1,
@@ -3869,12 +3863,14 @@ cdreportkey(struct cam_periph *periph, s
 		goto bailout;
 		break; /* NOTREACHED */
 	}
+
 bailout:
+	xpt_release_ccb(ccb);
+	cam_periph_unlock(periph);
+
 	if (databuf != NULL)
 		free(databuf, M_DEVBUF);
 
-	xpt_release_ccb(ccb);
-
 	return(error);
 }
 
@@ -3889,8 +3885,6 @@ cdsendkey(struct cam_periph *periph, str
 	error = 0;
 	databuf = NULL;
 
-	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
-
 	switch(authinfo->format) {
 	case DVD_SEND_CHALLENGE: {
 		struct scsi_report_key_data_challenge *challenge_data;
@@ -3942,11 +3936,12 @@ cdsendkey(struct cam_periph *periph, str
 		break;
 	}
 	default:
-		error = EINVAL;
-		goto bailout;
-		break; /* NOTREACHED */
+		return (EINVAL);
 	}
 
+	cam_periph_lock(periph);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
+
 	scsi_send_key(&ccb->csio,
 		      /* retries */ 1,
 		      /* cbfcnp */ cddone,
@@ -3961,13 +3956,12 @@ cdsendkey(struct cam_periph *periph, str
 	error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO,
 			 /*sense_flags*/SF_RETRY_UA);
 
-bailout:
+	xpt_release_ccb(ccb);
+	cam_periph_unlock(periph);
 
 	if (databuf != NULL)
 		free(databuf, M_DEVBUF);
 
-	xpt_release_ccb(ccb);
-
 	return(error);
 }
 
@@ -3985,8 +3979,6 @@ cdreaddvdstructure(struct cam_periph *pe
 	/* The address is reserved for many of the formats */
 	address = 0;
 
-	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
-
 	switch(dvdstruct->format) {
 	case DVD_STRUCT_PHYSICAL:
 		length = sizeof(struct scsi_read_dvd_struct_data_physical);
@@ -4004,13 +3996,7 @@ cdreaddvdstructure(struct cam_periph *pe
 		length = sizeof(struct scsi_read_dvd_struct_data_manufacturer);
 		break;
 	case DVD_STRUCT_CMI:
-		error = ENODEV;
-		goto bailout;
-#ifdef notyet
-		length = sizeof(struct scsi_read_dvd_struct_data_copy_manage);
-		address = dvdstruct->address;
-#endif
-		break; /* NOTREACHED */
+		return (ENODEV);
 	case DVD_STRUCT_PROTDISCID:
 		length = sizeof(struct scsi_read_dvd_struct_data_prot_discid);
 		break;
@@ -4027,21 +4013,9 @@ cdreaddvdstructure(struct cam_periph *pe
 		length = sizeof(struct scsi_read_dvd_struct_data_spare_area);
 		break;
 	case DVD_STRUCT_RMD_LAST:
-		error = ENODEV;
-		goto bailout;
-#ifdef notyet
-		length = sizeof(struct scsi_read_dvd_struct_data_rmd_borderout);
-		address = dvdstruct->address;
-#endif
-		break; /* NOTREACHED */
+		return (ENODEV);
 	case DVD_STRUCT_RMD_RMA:
-		error = ENODEV;
-		goto bailout;
-#ifdef notyet
-		length = sizeof(struct scsi_read_dvd_struct_data_rmd);
-		address = dvdstruct->address;
-#endif
-		break; /* NOTREACHED */
+		return (ENODEV);
 	case DVD_STRUCT_PRERECORDED:
 		length = sizeof(struct scsi_read_dvd_struct_data_leadin);
 		break;
@@ -4049,13 +4023,7 @@ cdreaddvdstructure(struct cam_periph *pe
 		length = sizeof(struct scsi_read_dvd_struct_data_disc_id);
 		break;
 	case DVD_STRUCT_DCB:
-		error = ENODEV;
-		goto bailout;
-#ifdef notyet
-		length = sizeof(struct scsi_read_dvd_struct_data_dcb);
-		address = dvdstruct->address;
-#endif
-		break; /* NOTREACHED */
+		return (ENODEV);
 	case DVD_STRUCT_LIST:
 		/*
 		 * This is the maximum allocation length for the READ DVD
@@ -4067,9 +4035,7 @@ cdreaddvdstructure(struct cam_periph *pe
 		length = 65535;
 		break;
 	default:
-		error = EINVAL;
-		goto bailout;
-		break; /* NOTREACHED */
+		return (EINVAL);
 	}
 
 	if (length != 0) {
@@ -4077,6 +4043,9 @@ cdreaddvdstructure(struct cam_periph *pe
 	} else
 		databuf = NULL;
 
+	cam_periph_lock(periph);
+	ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
+
 	scsi_read_dvd_structure(&ccb->csio,
 				/* retries */ 1,
 				/* cbfcnp */ cddone,
@@ -4164,13 +4133,14 @@ cdreaddvdstructure(struct cam_periph *pe
 		      min(sizeof(dvdstruct->data), dvdstruct->length));
 		break;
 	}
+
 bailout:
+	xpt_release_ccb(ccb);
+	cam_periph_unlock(periph);
 
 	if (databuf != NULL)
 		free(databuf, M_DEVBUF);
 
-	xpt_release_ccb(ccb);
-
 	return(error);
 }
 


More information about the svn-src-all mailing list