patch-2.4.10 linux/drivers/scsi/sg.c

Next file: linux/drivers/scsi/sgiwd93.c
Previous file: linux/drivers/scsi/seagate.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.9/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
@@ -19,9 +19,9 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.19 (20010623)";
+ static char sg_version_str[] = "Version: 3.1.20 (20010814)";
 #endif
- static int sg_version_num = 30119; /* 2 digits for each component */
+ static int sg_version_num = 30120; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -271,6 +271,7 @@
      /* Prevent the device driver from vanishing while we sleep */
      if (sdp->device->host->hostt->module)
         __MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
+    sdp->device->access_count++;
 
     if (! ((flags & O_NONBLOCK) ||
 	   scsi_block_when_processing_errors(sdp->device))) {
@@ -323,6 +324,7 @@
     return 0;
 
 error_out:
+    sdp->device->access_count--;
     if ((! sdp->detached) && sdp->device->host->hostt->module)
         __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
     return retval;
@@ -342,8 +344,11 @@
     SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev)));
     sg_fasync(-1, filp, 0);   /* remove filp from async notification list */
     if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */
-	if ((! sdp->detached) && sdp->device->host->hostt->module)
-	    __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+        if (! sdp->detached) {
+            sdp->device->access_count--;
+            if (sdp->device->host->hostt->module)
+                __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+        }
 	sdp->exclude = 0;
 	wake_up_interruptible(&sdp->o_excl_wait);
     }
@@ -640,6 +645,7 @@
     Scsi_Request        * SRpnt;
     Sg_device           * sdp = sfp->parentdp;
     sg_io_hdr_t         * hp = &srp->header;
+    request_queue_t	* q;
 
     srp->data.cmd_opcode = cmnd[0];  /* hold opcode of command */
     hp->status = 0;
@@ -675,6 +681,7 @@
     }
 
     srp->my_cmdp = SRpnt;
+    q = &SRpnt->sr_device->request_queue;
     SRpnt->sr_request.rq_dev = sdp->i_rdev;
     SRpnt->sr_request.rq_status = RQ_ACTIVE;
     SRpnt->sr_sense_buffer[0] = 0;
@@ -710,7 +717,7 @@
 		(void *)SRpnt->sr_buffer, hp->dxfer_len,
 		sg_cmd_done_bh, timeout, SG_DEFAULT_RETRIES);
     /* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-    generic_unplug_device(&SRpnt->sr_device->request_queue);
+    generic_unplug_device(q);
     return 0;
 }
 
@@ -874,6 +881,9 @@
         return 0;
     case SG_GET_VERSION_NUM:
         return put_user(sg_version_num, (int *)arg);
+    case SG_GET_ACCESS_COUNT:
+    	val = (sdp->device ? sdp->device->access_count : 0);
+	return put_user(val, (int *)arg);
     case SG_GET_REQUEST_TABLE:
 	result = verify_area(VERIFY_WRITE, (void *) arg,
 			     SZ_SG_REQ_INFO * SG_MAX_QUEUE);
@@ -1116,6 +1126,7 @@
             sg_remove_sfp(sdp, sfp);
 	    sfp = NULL;
         }
+	sdp->device->access_count--;
 	if (sg_template.module)
 		__MOD_DEC_USE_COUNT(sg_template.module);
 	if (sdp->device->host->hostt->module)
@@ -1241,6 +1252,15 @@
 
     for(k = 0; k < sg_template.dev_max; k++)
         if(! sg_dev_arr[k]) break;
+    if (k > MINORMASK) {
+	scsidp->attached--;
+	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+	printk("Unable to attach sg device <%d, %d, %d, %d>"
+	       " type=%d, minor number exceed %d\n", scsidp->host->host_no, 
+	       scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,
+	       MINORMASK);
+	return 1;
+    }
     if(k < sg_template.dev_max)
     	sdp = (Sg_device *)kmalloc(sizeof(Sg_device), GFP_ATOMIC);
     else
@@ -1264,7 +1284,7 @@
     sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,
                              SCSI_GENERIC_MAJOR, k,
                              S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
-                             &sg_fops, NULL);
+                             &sg_fops, sdp);
     sg_template.nr_dev++;
     sg_dev_arr[k] = sdp;
     write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
@@ -1314,6 +1334,7 @@
 			sg_finish_rem_req(srp);
 		}
 		if (sfp->closed) {
+		    sdp->device->access_count--;
 		    if (sg_template.module)
 			__MOD_DEC_USE_COUNT(sg_template.module);
 		    if (sdp->device->host->hostt->module)
@@ -2210,6 +2231,7 @@
     }
     else {
         sfp->closed = 1; /* flag dirty state on this fd */
+	sdp->device->access_count++;
 	/* MOD_INC's to inhibit unloading sg and associated adapter driver */
 	if (sg_template.module)
 	    __MOD_INC_USE_COUNT(sg_template.module);
@@ -2753,7 +2775,7 @@
 static int sg_proc_devhdr_info(char * buffer, int * len, off_t * begin,
 			       off_t offset, int size)
 {
-    PRINT_PROC("host\tchan\tid\tlun\ttype\tbopens\tqdepth\tbusy\tonline\n");
+    PRINT_PROC("host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n");
     return 1;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)