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
- Lines: 353
- Date:
Sun Jan 26 12:07:21 1997
- Orig file:
v2.1.22/linux/drivers/scsi/sg.c
- Orig date:
Mon Dec 30 15:39:11 1996
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