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

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

diff -u --recursive --new-file v2.1.22/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
@@ -1,9 +1,9 @@
 /*
  *  History:
- *  Started: Aug 9 by Lawrence Foard (entropy@world.std.com), 
+ *  Started: Aug 9 by Lawrence Foard (entropy@world.std.com),
  *           to allow user process control of SCSI devices.
  *  Development Sponsored by Killy Corp. NY NY
- *   
+ *
  *  Borrows code from st driver.
  */
 #include <linux/module.h>
@@ -17,6 +17,7 @@
 #include <linux/mtio.h>
 #include <linux/ioctl.h>
 #include <linux/fcntl.h>
+#include <linux/poll.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -33,7 +34,7 @@
 static void sg_detach(Scsi_Device *);
 
 
-struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", NULL, 0xff, 
+struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", NULL, 0xff,
 					       SCSI_GENERIC_MAJOR, 0, 0, 0, 0,
 					       sg_detect, sg_init,
 					       NULL, sg_attach, sg_detach};
@@ -129,7 +130,7 @@
      * that other processes know that we have it, and initialize the
      * state variables to known values.
      */
-    if (!scsi_generics[dev].users 
+    if (!scsi_generics[dev].users
         && scsi_generics[dev].pending
         && scsi_generics[dev].complete)
     {
@@ -140,9 +141,10 @@
     }
     if (!scsi_generics[dev].users)
 	scsi_generics[dev].timeout=SG_DEFAULT_TIMEOUT;
-    if (scsi_generics[dev].device->host->hostt->usage_count)
-	(*scsi_generics[dev].device->host->hostt->usage_count)++;
-    if(sg_template.usage_count) (*sg_template.usage_count)++;
+    if (scsi_generics[dev].device->host->hostt->module)
+	__MOD_INC_USE_COUNT(scsi_generics[dev].device->host->hostt->module);
+    if (sg_template.module)
+        __MOD_INC_USE_COUNT(sg_template.module);
     scsi_generics[dev].users++;
     return 0;
 }
@@ -151,9 +153,10 @@
 {
     int dev=MINOR(inode->i_rdev);
     scsi_generics[dev].users--;
-    if (scsi_generics[dev].device->host->hostt->usage_count)
-	(*scsi_generics[dev].device->host->hostt->usage_count)--;
-    if(sg_template.usage_count) (*sg_template.usage_count)--;
+    if (scsi_generics[dev].device->host->hostt->module)
+	__MOD_DEC_USE_COUNT(scsi_generics[dev].device->host->hostt->module);
+    if(sg_template.module)
+        __MOD_DEC_USE_COUNT(sg_template.module);
     scsi_generics[dev].exclude=0;
     wake_up(&scsi_generics[dev].generic_wait);
 }
@@ -174,11 +177,11 @@
 	big_inuse=1;
 	return big_buff;
     }
-#endif   
+#endif
     return NULL;
 }
 
-static void sg_free(char *buff,int size) 
+static void sg_free(char *buff,int size)
 {
 #ifdef SG_BIG_BUFF
     if (buff==big_buff)
@@ -243,7 +246,7 @@
     }
     else
 	count= device->header.result==0 ? 0 : -EIO;
-    
+
     /*
      * Clean up, and release the device so that we can send another
      * command.
@@ -283,14 +286,14 @@
       break;
     case DID_NO_CONNECT:
     case DID_BUS_BUSY:
-    case DID_TIME_OUT: 
+    case DID_TIME_OUT:
       device->header.result = EBUSY;
       break;
-    case DID_BAD_TARGET: 
-    case DID_ABORT: 
-    case DID_PARITY: 
+    case DID_BAD_TARGET:
+    case DID_ABORT:
+    case DID_PARITY:
     case DID_RESET:
-    case DID_BAD_INTR: 
+    case DID_BAD_INTR:
       device->header.result = EIO;
       break;
     case DID_ERROR:
@@ -328,12 +331,12 @@
     int			  input_size;
     unsigned char	  opcode;
     Scsi_Cmnd		* SCpnt;
-    
+
     if ((i=verify_area(VERIFY_READ,buf,count)))
 	return i;
     /*
      * The minimum scsi command length is 6 bytes.  If we get anything
-     * less than this, it is clearly bogus.  
+     * less than this, it is clearly bogus.
      */
     if (count<(sizeof(struct sg_header) + 6))
 	return -EIO;
@@ -349,7 +352,7 @@
 	    return -EAGAIN;
 #ifdef DEBUG
 	printk("sg_write: sleeping on pending request\n");
-#endif     
+#endif
 	interruptible_sleep_on(&device->write_wait);
 	if (current->signal & ~current->blocked)
 	    return -ERESTARTSYS;
@@ -382,7 +385,7 @@
     } else {
         bsize = device->header.reply_len;
     }
-    
+
     /*
      * Don't include the command header itself in the size.
      */
@@ -398,7 +401,7 @@
         wake_up( &device->write_wait );
 	return -EIO;
     }
-    
+
     /*
      * Allocate a buffer that is large enough to hold the data
      * that has been requested.  Round up to an even number of sectors,
@@ -434,10 +437,10 @@
 	sg_free(device->buff,device->buff_len);
 	device->buff = NULL;
 	return -EAGAIN;
-    } 
+    }
 #ifdef DEBUG
     printk("device allocated\n");
-#endif    
+#endif
 
     SCpnt->request.rq_dev = devt;
     SCpnt->request.rq_status = RQ_ACTIVE;
@@ -456,7 +459,7 @@
      * so we need to subtract these off.
      */
     if (input_size > 0) copy_from_user(device->buff, buf, input_size);
-    
+
     /*
      * Set the LUN field in the command structure.
      */
@@ -477,36 +480,25 @@
 
 #ifdef DEBUG
     printk("done cmd\n");
-#endif               
+#endif
 
     return count;
 }
 
-static int sg_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
+static unsigned int sg_poll(struct file *file, poll_table * wait)
 {
-    int dev=MINOR(inode->i_rdev);
-    int r = 0;
-    struct scsi_generic *device=&scsi_generics[dev];
+        int dev = MINOR(file->f_inode->i_rdev);
+        struct scsi_generic *device = &scsi_generics[dev];
+        unsigned int mask = 0;
 
-    if (sel_type == SEL_IN) {
+        poll_wait(&scsi_generics[dev].read_wait, wait);
+        poll_wait(&scsi_generics[dev].write_wait, wait);
         if(device->pending && device->complete)
-        {
-            r = 1;
-    	} else {
-	    select_wait(&scsi_generics[dev].read_wait, wait);
-    	}
-    }
-    if (sel_type == SEL_OUT) {
-        if(!device->pending){
-            r = 1;
-        }
-        else
-        {
-	    select_wait(&scsi_generics[dev].write_wait, wait);
-        }
-    }
+                mask |= POLLIN | POLLRDNORM;
+        if(!device->pending)
+                mask |= POLLOUT | POLLWRNORM;
 
-    return(r);
+        return mask;
 }
 
 static struct file_operations sg_fops = {
@@ -514,7 +506,7 @@
     sg_read,         /* read */
     sg_write,        /* write */
     NULL,            /* readdir */
-    sg_select,       /* select */
+    sg_poll,         /* poll */
     sg_ioctl,        /* ioctl */
     NULL,            /* mmap */
     sg_open,         /* open */
@@ -531,7 +523,7 @@
 	case TYPE_ROM:
 	case TYPE_WORM:
 	case TYPE_TAPE: break;
-	default: 
+	default:
 	printk("Detected scsi generic sg%c at scsi%d, channel %d, id %d, lun %d\n",
            'a'+sg_template.dev_noticed,
            SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
@@ -544,11 +536,11 @@
 static int sg_init()
 {
     static int sg_registered = 0;
-    
+
     if (sg_template.dev_noticed == 0) return 0;
-    
+
     if(!sg_registered) {
-	if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops)) 
+	if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
 	{
 	    printk("Unable to get major %d for generic SCSI device\n",
 		   SCSI_GENERIC_MAJOR);
@@ -556,24 +548,24 @@
 	}
 	sg_registered++;
     }
-    
+
     /* If we have already been through here, return */
     if(scsi_generics) return 0;
-    
+
 #ifdef DEBUG
     printk("sg: Init generic device.\n");
 #endif
-    
+
 #ifdef SG_BIG_BUFF
     big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF, GFP_ATOMIC | GFP_DMA);
 #endif
-    
-    scsi_generics = (struct scsi_generic *) 
-	scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS) 
+
+    scsi_generics = (struct scsi_generic *)
+	scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS)
 			 * sizeof(struct scsi_generic), GFP_ATOMIC);
     memset(scsi_generics, 0, (sg_template.dev_noticed + SG_EXTRA_DEVS)
 	   * sizeof(struct scsi_generic));
-    
+
     sg_template.dev_max = sg_template.dev_noticed + SG_EXTRA_DEVS;
     return 0;
 }
@@ -582,18 +574,18 @@
 {
     struct scsi_generic * gpnt;
     int i;
-    
-    if(sg_template.nr_dev >= sg_template.dev_max) 
+
+    if(sg_template.nr_dev >= sg_template.dev_max)
     {
 	SDp->attached--;
 	return 1;
     }
-    
-    for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++) 
+
+    for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
 	if(!gpnt->device) break;
-    
+
     if(i >= sg_template.dev_max) panic ("scsi_devices corrupt (sg)");
-    
+
     scsi_generics[i].device=SDp;
     scsi_generics[i].users=0;
     scsi_generics[i].generic_wait=NULL;
@@ -613,14 +605,14 @@
 {
     struct scsi_generic * gpnt;
     int i;
-    
-    for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++) 
+
+    for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
 	if(gpnt->device == SDp) {
 	    gpnt->device = NULL;
 	    SDp->attached--;
 	    sg_template.nr_dev--;
-            /* 
-             * avoid associated device /dev/sg? bying incremented 
+            /*
+             * avoid associated device /dev/sg? bying incremented
              * each time module is inserted/removed , <dan@lectra.fr>
              */
             sg_template.dev_noticed--;
@@ -632,18 +624,18 @@
 #ifdef MODULE
 
 int init_module(void) {
-    sg_template.usage_count = &__this_module.usecount;
+    sg_template.module = &__this_module;
     return scsi_register_module(MODULE_SCSI_DEV, &sg_template);
 }
 
-void cleanup_module( void) 
+void cleanup_module( void)
 {
     scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);
     unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
-    
+
     if(scsi_generics != NULL) {
 	scsi_init_free((char *) scsi_generics,
-		       (sg_template.dev_noticed + SG_EXTRA_DEVS) 
+		       (sg_template.dev_noticed + SG_EXTRA_DEVS)
 		       * sizeof(struct scsi_generic));
     }
     sg_template.dev_max = 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov