PERFORCE change 50770 for review

Scott Long scottl at FreeBSD.org
Fri Apr 9 23:32:42 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=50770

Change 50770 by scottl at scottl-junior-camlock on 2004/04/09 23:31:42

	Don peril-sensitive eyewear and convert probestart() to use
	workitems instead of calling xpt_action() directly.  The workitem
	is pre-allocated in proberegister().  Also add a helper method for
	safely queueing work items, and change the locking slightly to not
	drop the workitem mutex once the item is safely off the list.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#3 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#3 (text+ko) ====

@@ -81,6 +81,17 @@
 PERIPHDRIVER_DECLARE(probe, probe_driver);
 
 typedef enum {
+	WORK_EXECUTE_CCB = 0x1,
+} cam_workflags;
+
+struct cam_workitem {
+	TAILQ_ENTRY(cam_workitem)	work_links;
+	cam_workflags			command;
+	void				*data;
+	void				(*cbfcnp)(void *);
+};
+
+typedef enum {
 	PROBE_TUR,
 	PROBE_INQUIRY,
 	PROBE_FULL_INQUIRY,
@@ -102,19 +113,9 @@
 	probe_flags	flags;
 	MD5_CTX		context;
 	u_int8_t	digest[16];
+	struct cam_workitem *work;
 } probe_softc;
 
-typedef enum {
-	WORK_EXECUTE_CCB = 0x1,
-} cam_workflags;
-
-struct cam_workitem {
-	TAILQ_ENTRY(cam_workitem)	work_links;
-	cam_workflags			command;
-	void				*data;
-	void				(*cbfcnp)(void *);
-};
-
 static struct proc *probe_proc;
 static struct mtx probe_workmtx;
 static int probe_workflags;
@@ -123,6 +124,15 @@
 #define PROBE_FLAG_EXIT	0x1
 
 static void
+probe_queue_work(struct cam_workitem *work)
+{
+	mtx_lock(&probe_workmtx);
+	TAILQ_INSERT_TAIL(&probe_worklist, work, work_links);
+	mtx_unlock(&probe_workmtx);
+	wakeup(&probe_worklist);
+}
+
+static void
 probe_work(void *dummy)
 {
 	struct cam_workitem *work;
@@ -135,6 +145,7 @@
 			continue;
 		}
 		TAILQ_REMOVE(&probe_worklist, work, work_links);
+		mtx_unlock(&probe_workmtx);
 
 		switch (work->command) {
 		case WORK_EXECUTE_CCB:
@@ -143,6 +154,11 @@
 		default:
 			panic("Unknown CAM work item %d\n", work->command);
 		}
+
+		if (work->cbfcnp != NULL)
+			work->cbfcnp(work->data);
+
+		mtx_lock(&probe_workmtx);
 	}
 	mtx_unlock(&probe_workmtx);
 
@@ -164,6 +180,7 @@
 {
 	union ccb *request_ccb;	/* CCB representing the probe request */
 	probe_softc *softc;
+	struct cam_workitem *work;
 
 	request_ccb = (union ccb *)arg;
 	if (periph == NULL) {
@@ -184,6 +201,16 @@
 		       "Unable to allocate softc\n");				
 		return(CAM_REQ_CMP_ERR);
 	}
+	
+	work = malloc(sizeof(struct cam_workitem), M_TEMP, M_NOWAIT | M_ZERO);
+	if (work == NULL) {
+		printf("proberegister: Unable to probe new device. "
+		       "Unable to allocate softc\n");
+		free(softc, M_TEMP);
+		return (CAM_REQ_CMP_ERR);
+	}
+
+	softc->work = work;
 	TAILQ_INIT(&softc->request_ccbs);
 	TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
 			  periph_links.tqe);
@@ -388,7 +415,11 @@
 		return;
 	}
 	}
-	xpt_action(start_ccb);
+
+	softc->work->command = WORK_EXECUTE_CCB;
+	softc->work->data = start_ccb;
+	softc->work->cbfcnp = NULL;
+	probe_queue_work(softc->work);
 }
 
 static void
@@ -702,6 +733,7 @@
 static void
 probecleanup(struct cam_periph *periph)
 {
+	free(((probe_softc *)(periph->softc))->work, M_TEMP);
 	free(periph->softc, M_TEMP);
 }
 


More information about the p4-projects mailing list