VERSION = 1
PATCHLEVEL = 1
-SUBLEVEL = 27
+SUBLEVEL = 28
all: Version zImage
static int curr_control_reg = 0; /* Current value of the control register */
-
-#if 1 /* This will go away as soon as the isofs code is fixed
- to use the fops struct. */
-/*
- * This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't. Setting flag to 0 resets the changed flag.
- */
-int
-check_cdu31a_media_change(int full_dev, int flag)
-{
- int retval, target;
-
-
- target = MINOR(full_dev);
-
- if (target > 0) {
- printk("Sony CD-ROM request error: invalid device.\n");
- return 0;
- }
-
- retval = sony_disc_changed;
- if (!flag)
- {
- sony_disc_changed = 0;
- }
-
- return retval;
-}
-#endif
-
/*
* This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't. Setting flag to 0 resets the changed flag.
+ * check or 0 if it hasn't.
*/
static int
scd_disk_change(dev_t full_dev)
} else
/* not offline or out of paper. on fire? */
if (!(status & LP_PERRORP)) {
- printk("lp%d on fire\n", minor);
+ printk("lp%d reported invalid error status (on fire, eh?)\n", minor);
if(LP_F(minor) & LP_ABORT)
return temp-buf?temp-buf:-EFAULT;
current->state = TASK_INTERRUPTIBLE;
if (driver->subtype == PTY_TYPE_MASTER)
(*o_tty_loc)->count++;
}
+ (*tty_loc)->driver = *driver;
*ret_tty = *tty_loc;
retval = 0;
end_init:
+Sat Jul 9 15:01:03 1994 Eric Youngdale (eric@esp22)
+
+ More changes to eventually support loadable modules. Mainly
+ we want to use linked lists instead of arrays because it is easier
+ to dynamically add and remove things this way.
+
+ Quite a bit more work is needed before loadable modules are
+ possible (and usable) with scsi, but this is most of the grunge
+ work.
+
+ * Linux 1.1.28 released.
+
+ * scsi.c, scsi.h (allocate_device, request_queueable): Change
+ argument from index into scsi_devices to a pointer to the
+ Scsi_Device struct.
+
+ * Throughout: Change all calls to allocate_device,
+ request_queueable to use new calling sequence.
+
+ * Throughout: Use SCpnt->device instead of
+ scsi_devices[SCpnt->index]. Ugh - the pointer was there all along
+ - much cleaner this way.
+
+ * scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
+ allow us to pretend that we have a working malloc when we
+ initialize. Use this instead of passing memory_start, memory_end
+ around all over the place.
+
+ * scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
+ scsi_init_malloc, remove all arguments, no return value.
+
+ * scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
+ structs.
+
+ * scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
+ (scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
+ when we discover a device. Free pointer before returning.
+ Change scsi_devices into a linked list.
+
+ * scsi.c (scan_scsis): Change to only scan one host.
+ (scsi_dev_init): Loop over all detected hosts, and scan them.
+
+ * hosts.c (scsi_init_free): Change so that number of extra bytes
+ is stored in struct, and we do not have to pass it each time.
+
+ * hosts.h: Change Scsi_Host_Template struct to include "next" and
+ "release" functions. Initialize to NULL in all low level
+ adapters.
+
+ * hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
+ list scsi_hosts, linked together with the new "next" field.
+
Wed Jul 6 05:45:02 1994 Eric Youngdale (eric@esp22)
* Linux 1.1.25 released.
+ * aha152x.c: Changes from Juergen - cleanups and updates.
+
* sd.c, sr.c: Use new check_media_change and revalidate
file_operations fields.
ICR_ASSERT_ATN | ICR_ASSERT_SEL));
/*
- * Something wierd happens when we cease to drive BSY - looks
+ * Something weird happens when we cease to drive BSY - looks
* like the board/chip is letting us do another read before the
* appropriate propogation delay has expired, and we're confusing
* a BSY signal from ourselves as the target's response to SELECTION.
#endif
tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
#ifdef SCSI2
- if (scsi_devices[cmd->index].tagged_queue && (tag != TAG_NONE)) {
+ if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
tmp[1] = SIMPLE_QUEUE_TAG;
if (tag == TAG_NEXT) {
/* 0 is TAG_NONE, used to imply no tag for this command */
- if (scsi_devices[cmd->index].current_tag == 0)
- scsi_devices[cmd->index].current_tag = 1;
+ if (cmd->device->current_tag == 0)
+ cmd->device->current_tag = 1;
- cmd->tag = scsi_devices[cmd->index].current_tag;
- scsi_devices[cmd->index].current_tag++;
+ cmd->tag = cmd->device->current_tag;
+ cmd->device->current_tag++;
} else
cmd->tag = (unsigned char) tag;
/* XXX need to handle errors here */
hostdata->connected = cmd;
#ifdef SCSI2
- if (!scsi_devices[cmd->index].tagged_queue)
+ if (!cmd->device->tagged_queue)
#endif
hostdata->busy[cmd->target] |= (1 << cmd->lun);
#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
#ifdef NCR5380_dma_xfer_len
- if (!scsi_devices[cmd->index].borken &&
+ if (!cmd->device->borken &&
(transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
#else
- if (!scsi_devices[cmd->index].borken &&
+ if (!cmd->device->borken &&
(transfersize = cmd->transfersize) &&
cmd->SCp.this_residual && !(cmd->SCp.this_residual %
transfersize)) {
*/
printk("scsi%d : switching target %d lun %d to slow handshake\n",
instance->host_no, cmd->target, cmd->lun);
- scsi_devices[cmd->index].borken = 1;
+ cmd->device->borken = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
ICR_ASSERT_ATN);
msgout = ABORT;
case HEAD_OF_QUEUE_TAG:
case ORDERED_QUEUE_TAG:
case SIMPLE_QUEUE_TAG:
- scsi_devices[cmd->index].tagged_queue = 0;
+ cmd->device->tagged_queue = 0;
hostdata->busy[cmd->target] |= (1 << cmd->lun);
break;
default:
break;
}
case DISCONNECT:
- scsi_devices[cmd->index].disconnect = 1;
+ cmd->device->disconnect = 1;
cli();
cmd->host_scribble = (unsigned char *)
hostdata->disconnected_queue;
return(i==16);
}
-int aha152x_detect(int hostno)
+int aha152x_detect(Scsi_Host_Template * tpnt)
{
int i, j, ok;
aha152x_config conf;
}
SETPORT( SCSIID, this_host << 4 );
- scsi_hosts[hostno].this_id=this_host;
+ tpnt->this_id=this_host;
if(can_disconnect)
- scsi_hosts[hostno].can_queue=AHA152X_MAXQUEUE;
+ tpnt->can_queue=AHA152X_MAXQUEUE;
/* RESET OUT */
SETBITS(SCSISEQ, SCSIRSTO );
#if defined(__KERNEL__)
#include <asm/io.h>
-int aha152x_detect(int);
+int aha152x_detect(Scsi_Host_Template *);
const char *aha152x_info(void);
int aha152x_command(Scsi_Cmnd *);
int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.2 $"
/* Initial value of Scsi_Host entry */
-#define AHA152X { /* name */ AHA152X_REVID, \
+#define AHA152X { /* next */ NULL, \
+ /* name */ AHA152X_REVID, \
/* detect */ aha152x_detect, \
+ /* release */ NULL, \
/* info */ aha152x_info, \
/* command */ aha152x_command, \
/* queuecommand */ aha152x_queue, \
/* return non-zero on detection */
-int aha1542_detect(int hostnum)
+int aha1542_detect(Scsi_Host_Template * tpnt)
{
unsigned char dma_chan;
unsigned char irq_level;
for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
if(!check_region(bases[indx], 4)) {
- shpnt = scsi_register(hostnum,
+ shpnt = scsi_register(tpnt,
sizeof(struct aha1542_hostdata));
if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
count++;
continue;
unregister:
- scsi_unregister(shpnt, sizeof(struct aha1542_hostdata));
+ scsi_unregister(shpnt);
continue;
};
/* REQUEST SENSE */
};
-int aha1542_detect(int);
+int aha1542_detect(Scsi_Host_Template *);
int aha1542_command(Scsi_Cmnd *);
int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int aha1542_abort(Scsi_Cmnd *);
#define NULL 0
#endif
-#define AHA1542 {"Adaptec 1542", aha1542_detect, \
- aha1542_info, aha1542_command, \
- aha1542_queuecommand, \
- aha1542_abort, \
- aha1542_reset, \
- NULL, \
- aha1542_biosparam, \
- AHA1542_MAILBOXES, 7, AHA1542_SCATTER, AHA1542_CMDLUN \
- , 0, 1, ENABLE_CLUSTERING}
+#define AHA1542 { NULL, \
+ "Adaptec 1542", \
+ aha1542_detect, \
+ NULL, \
+ aha1542_info, \
+ aha1542_command, \
+ aha1542_queuecommand, \
+ aha1542_abort, \
+ aha1542_reset, \
+ NULL, \
+ aha1542_biosparam, \
+ AHA1542_MAILBOXES, \
+ 7, \
+ AHA1542_SCATTER, \
+ AHA1542_CMDLUN, \
+ 0, \
+ 1, \
+ ENABLE_CLUSTERING}
#endif
irq_level = intab [ inb(INTDEF)&0x7 ];
}
-int aha1740_detect(int hostnum)
+int aha1740_detect(Scsi_Host_Template * tpnt)
{
memset(&ecb, 0, sizeof(struct ecb));
DEB(printk("aha1740_detect: \n"));
#define AHA1740CMD_RINQ 0x0a /* Read Host Adapter Inquiry Data */
#define AHA1740CMD_TARG 0x10 /* Target SCSI Command */
-int aha1740_detect(int);
+int aha1740_detect(Scsi_Host_Template *);
int aha1740_command(Scsi_Cmnd *);
int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int aha1740_abort(Scsi_Cmnd *);
#define NULL 0
#endif
-#define AHA1740 {"Adaptec 1740", aha1740_detect, \
- aha1740_info, aha1740_command, \
- aha1740_queuecommand, \
- aha1740_abort, \
- aha1740_reset, \
- NULL, \
- aha1740_biosparam, \
- AHA1740_ECBS, 7, AHA1740_SCATTER, 1, 0, 0, ENABLE_CLUSTERING}
+#define AHA1740 {NULL, \
+ "Adaptec 1740", \
+ aha1740_detect, \
+ NULL, \
+ aha1740_info, \
+ aha1740_command, \
+ aha1740_queuecommand, \
+ aha1740_abort, \
+ aha1740_reset, \
+ NULL, \
+ aha1740_biosparam, \
+ AHA1740_ECBS, \
+ 7, \
+ AHA1740_SCATTER, \
+ 1, \
+ 0, \
+ 0, \
+ ENABLE_CLUSTERING}
#endif
}
/* return non-zero on detection */
-int buslogic_detect(int hostnum)
+int buslogic_detect(Scsi_Host_Template * tpnt)
{
unsigned char dma;
unsigned char irq;
for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
if (!check_region(bases[indx], 3)) {
- SHpnt = scsi_register(hostnum, sizeof (struct hostdata));
+ SHpnt = scsi_register(tpnt, sizeof (struct hostdata));
base = bases[indx];
count++;
continue;
unregister:
- scsi_unregister(SHpnt, sizeof (struct hostdata));
+ scsi_unregister(SHpnt);
}
return count;
}
#ifndef _BUSLOGIC_H
-int buslogic_detect(int);
+int buslogic_detect(Scsi_Host_Template *);
int buslogic_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int buslogic_abort(Scsi_Cmnd *);
const char *buslogic_info(void);
#define BUSLOGIC_CMDLUN 1 /* ??? */
-#define BUSLOGIC { "BusLogic", \
+#define BUSLOGIC { NULL, \
+ "BusLogic", \
buslogic_detect, \
+ NULL, \
buslogic_info, \
0, /* no command func */ \
buslogic_queuecommand, \
static int bios_major = 0;
static int bios_minor = 0;
static int interrupt_level = 0;
-static int this_host = 0;
static volatile int in_command = 0;
static Scsi_Cmnd *current_SC = NULL;
static enum chip_type chip = unknown;
return 0;
}
-int fdomain_16x0_detect( int hostnum )
+int fdomain_16x0_detect(Scsi_Host_Template * tpnt)
{
int i, j;
int flag = 0;
printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
#endif
return 0;
- }
-
- this_host = hostnum;
-
- /* Log IRQ with kernel */
+ } /* Log IRQ with kernel */
if (!interrupt_level) {
panic( "Future Domain: *NO* interrupt level selected!\n" );
if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
adapter_mask = 0x80;
- scsi_hosts[this_host].this_id = 7;
+ tpnt->this_id = 7;
}
#if DO_DETECT
printk( "Future Domain detection routine scanning for devices:\n" );
for (i = 0; i < 8; i++) {
SCinit.target = i;
- if (i == scsi_hosts[this_host].this_id) /* Skip host adapter */
+ if (i == tpnt->this_id) /* Skip host adapter */
continue;
memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
retcode = fdomain_16x0_command(&SCinit);
#ifndef _FDOMAIN_H
#define _FDOMAIN_H
-int fdomain_16x0_detect( int );
+int fdomain_16x0_detect( Scsi_Host_Template * );
int fdomain_16x0_command( Scsi_Cmnd * );
int fdomain_16x0_abort( Scsi_Cmnd *);
const char *fdomain_16x0_info( void );
int fdomain_16x0_biosparam(Disk *, int, int * );
-#define FDOMAIN_16X0 { "Future Domain TMC-16x0", \
+#define FDOMAIN_16X0 { NULL, \
+ "Future Domain TMC-16x0", \
fdomain_16x0_detect, \
+ NULL, \
fdomain_16x0_info, \
fdomain_16x0_command, \
fdomain_16x0_queue, \
fdomain_16x0_reset, \
NULL, \
fdomain_16x0_biosparam, \
- 1, 6, 64 /* SG_NONE */, 1 ,0, 0, DISABLE_CLUSTERING}
+ 1, \
+ 6, \
+ 64 /* SG_NONE */, \
+ 1, \
+ 0, \
+ 0, \
+ DISABLE_CLUSTERING}
#endif
SA_INTERRUPT , NULL };
/*
- * Function : int generic_NCR5380_detect(int hostno)
+ * Function : int generic_NCR5380_detect(Scsi_Host_Templace * tpnt)
*
* Purpose : initializes generic NCR5380 driver based on the
* command line / compile time port and irq definitions.
*
- * Inputs : hostno - id of this SCSI adapter.
+ * Inputs : tpnt - template for this SCSI adapter.
*
* Returns : 1 if a host adapter was found, 0 if not.
*
*/
-int generic_NCR5380_detect(int hostno) {
+int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
static int current_override = 0;
int count;
struct Scsi_Host *instance;
if (!(overrides[current_override].port))
continue;
- instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
+ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
instance->io_port = overrides[current_override].port;
NCR5380_init(instance);
if (instance->irq != IRQ_NONE)
if (irqaction (instance->irq, &sa)) {
printk("scsi%d : IRQ%d not free, interrupts disabled\n",
- hostno, instance->irq);
+ instance->host_no, instance->irq);
instance->irq = IRQ_NONE;
}
if (instance->irq == IRQ_NONE) {
- printk("scsi%d : interrupts not enabled. for better interactive performance,\n", hostno);
- printk("scsi%d : please jumper the board for a free IRQ.\n", hostno);
+ printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+ printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
printk("scsi%d : at port %d", instance->host_no, instance->io_port);
#ifndef ASM
int generic_NCR5380_abort(Scsi_Cmnd *);
-int generic_NCR5380_detect(int);
+int generic_NCR5380_detect(Scsi_Host_Template *);
const char *generic_NCR5380_info(void);
int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int generic_NCR5380_reset(Scsi_Cmnd *);
#ifdef HOSTS_C
-#define GENERIC_NCR5380 {"Trantor T128/T128F/T228", \
- generic_NCR5380_detect, generic_NCR5380_info, NULL, \
+#define GENERIC_NCR5380 {NULL, "Trantor T128/T128F/T228", \
+ generic_NCR5380_detect, NULL, generic_NCR5380_info, NULL, \
generic_NCR5380_queue_command, generic_NCR5380_abort, \
generic_NCR5380_reset, NULL, \
NULL, /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
* idiocy.
*/
-Scsi_Host_Template scsi_hosts[] =
+Scsi_Host_Template * scsi_hosts = NULL;
+
+static Scsi_Host_Template builtin_scsi_hosts[] =
{
#ifdef CONFIG_SCSI_ULTRASTOR
ULTRASTOR_14F,
#endif
};
-#define MAX_SCSI_HOSTS (sizeof(scsi_hosts) / sizeof(Scsi_Host_Template))
+#define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template))
/*
* Our semaphores and timeout counters, where size depends on MAX_SCSI_HOSTS here.
struct Scsi_Host * scsi_hostlist = NULL;
-static int scsi_init_memory_start = 0;
-
int max_scsi_hosts = 0;
static int next_host = 0;
void
-scsi_unregister(struct Scsi_Host * sh, int j){
+scsi_unregister(struct Scsi_Host * sh){
struct Scsi_Host * shpnt;
+ int j;
+
+ j = sh->extra_bytes;
- if(((unsigned int) sh) + sizeof(struct Scsi_Host) + j != scsi_init_memory_start)
- panic("Unable to unregister scsi host");
if(scsi_hostlist == sh)
scsi_hostlist = NULL;
else {
shpnt = scsi_hostlist;
while(shpnt->next != sh) shpnt = shpnt->next;
shpnt->next = shpnt->next->next;
-
};
next_host--;
- scsi_init_memory_start = (unsigned int) sh;
+ scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + j);
}
/* We call this when we come across a new host adapter. We only do this
once we are 100% sure that we want to use this host adapter - it is a
pain to reverse this, so we try and avoid it */
-struct Scsi_Host * scsi_register(int i, int j){
+struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
struct Scsi_Host * retval, *shpnt;
- retval = (struct Scsi_Host*) scsi_init_memory_start;
- scsi_init_memory_start += sizeof(struct Scsi_Host) + j;
+ retval = scsi_init_malloc(sizeof(struct Scsi_Host) + j);
retval->host_busy = 0;
+ if(j > 0xffff) panic("Too many extra bytes requested\n");
+ retval->extra_bytes = j;
+ retval->loaded_as_module = scsi_loadable_module_flag;
retval->host_no = next_host++;
retval->host_queue = NULL;
retval->host_wait = NULL;
retval->last_reset = 0;
retval->irq = 0;
- retval->hostt = &scsi_hosts[i];
+ retval->hostt = tpnt;
retval->next = NULL;
#ifdef DEBUG
printk("Register %x %x: %d %d\n", retval, retval->hostt, i, j);
/* The next three are the default values which can be overridden
if need be */
- retval->this_id = scsi_hosts[i].this_id;
- retval->sg_tablesize = scsi_hosts[i].sg_tablesize;
- retval->unchecked_isa_dma = scsi_hosts[i].unchecked_isa_dma;
+ retval->this_id = tpnt->this_id;
+ retval->sg_tablesize = tpnt->sg_tablesize;
+ retval->unchecked_isa_dma = tpnt->unchecked_isa_dma;
if(!scsi_hostlist)
scsi_hostlist = retval;
return retval;
}
-unsigned int
-scsi_init(unsigned long memory_start,unsigned long memory_end)
+unsigned int scsi_init()
{
static int called = 0;
int i, j, count, pcount;
-
+ Scsi_Host_Template * tpnt;
count = 0;
- if(called) return memory_start;
+ if(called) return 0;
- scsi_init_memory_start = memory_start;
called = 1;
- for (i = 0; i < MAX_SCSI_HOSTS; ++i)
+ for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++)
{
/*
* Initialize our semaphores. -1 is interpreted to mean
*/
pcount = next_host;
- if ((scsi_hosts[i].detect) &&
- (scsi_hosts[i].present =
- scsi_hosts[i].detect(i)))
+ if ((tpnt->detect) &&
+ (tpnt->present =
+ tpnt->detect(tpnt)))
{
/* The only time this should come up is when people use
some kind of patched driver of some kind or another. */
if(pcount == next_host) {
- if(scsi_hosts[i].present > 1)
+ if(tpnt->present > 1)
panic("Failure to register low-level scsi driver");
/* The low-level driver failed to register a driver. We
can do this now. */
- scsi_register(i,0);
+ scsi_register(tpnt,0);
};
- for(j = 0; j < scsi_hosts[i].present; j++)
+ tpnt->next = scsi_hosts;
+ scsi_hosts = tpnt;
+ for(j = 0; j < tpnt->present; j++)
printk ("scsi%d : %s\n",
- count++, scsi_hosts[i].name);
+ count++, tpnt->name);
}
}
printk ("scsi : %d hosts.\n", count);
max_scsi_hosts = count;
- return scsi_init_memory_start;
+ return 0;
}
#ifndef CONFIG_BLK_DEV_SD
unsigned long sd_init(unsigned long memory_start, unsigned long memory_end){
return memory_start;
};
-unsigned long sd_init1(unsigned long memory_start, unsigned long memory_end){
- return memory_start;
+void sd_init1(){
+ return;
};
void sd_attach(Scsi_Device * SDp){
};
unsigned long sr_init(unsigned long memory_start, unsigned long memory_end){
return memory_start;
};
-unsigned long sr_init1(unsigned long memory_start, unsigned long memory_end){
- return memory_start;
+void sr_init1(){
+ return;
};
void sr_attach(Scsi_Device * SDp){
};
unsigned long st_init(unsigned long memory_start, unsigned long memory_end){
return memory_start;
};
-unsigned long st_init1(unsigned long memory_start, unsigned long memory_end){
- return memory_start;
+void st_init1(){
+ return;
};
void st_attach(Scsi_Device * SDp){
};
unsigned long sg_init(unsigned long memory_start, unsigned long memory_end){
return memory_start;
};
-unsigned long sg_init1(unsigned long memory_start, unsigned long memory_end){
- return memory_start;
+void sg_init1(){
+ return;
};
void sg_attach(Scsi_Device * SDp){
};
typedef struct scsi_disk Disk;
-typedef struct
+typedef struct SHT
{
+
+ /* Used with loadable modules so we can construct a linked list. */
+ struct SHT * next;
+
/*
The name pointer is a pointer to the name of the SCSI
device detected.
especially that scsi_malloc/scsi_free must not be called.
*/
- int (* detect)(int);
+ int (* detect)(struct SHT *);
+ /* Used with loadable modules to unload the host structures */
+ int (*release)(struct Scsi_Host *);
/*
The info function will return whatever useful
information the developer sees fit.
struct Scsi_Host
{
struct Scsi_Host * next;
+ unsigned short extra_bytes;
volatile unsigned char host_busy;
char host_no; /* Used for IOCTL_GET_IDLUN */
int last_reset;
int this_id;
short unsigned int sg_tablesize;
unsigned unchecked_isa_dma:1;
+ /*
+ True if this host was loaded as a loadable module
+ */
+ unsigned loaded_as_module:1;
+
int hostdata[0]; /* Used for storage of host specific stuff */
};
extern struct Scsi_Host * scsi_hostlist;
-extern Scsi_Host_Template scsi_hosts[];
+extern Scsi_Host_Template * scsi_hosts;
/*
scsi_init initializes the scsi hosts.
*/
-unsigned int scsi_init(unsigned long memory_start,unsigned long memory_end);
-extern struct Scsi_Host * scsi_register(int i, int j);
-extern void scsi_unregister(struct Scsi_Host * i, int j);
+/* We use these goofy things because the MM is not set up when we init
+ the scsi subsystem. By using these functions we can write code that
+ looks normal. Also, it makes it possible to use the same code for a
+ loadable module. */
+
+extern void * scsi_init_malloc(unsigned int size);
+extern void scsi_init_free(char * ptr, unsigned int size);
+
+
+extern int scsi_loadable_module_flag;
+unsigned int scsi_init(void);
+extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j);
+extern void scsi_unregister(struct Scsi_Host * i);
#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#endif
static struct sigaction pas16_sigaction = { pas16_intr, 0, SA_INTERRUPT , NULL };
/*
- * Function : int pas16_detect(int hostno)
+ * Function : int pas16_detect(Scsi_Host_Template * tpnt)
*
* Purpose : detects and initializes PAS16 controllers
* that were autoprobed, overriden on the LILO command line,
* or specified at compile time.
*
- * Inputs : hostno - id of this SCSI adapter.
+ * Inputs : tpnt - template for this SCSI adapter.
*
* Returns : 1 if a host adapter was found, 0 if not.
*
*/
-int pas16_detect(int hostno) {
+int pas16_detect(Scsi_Host_Template * tpnt) {
static int current_override = 0;
static unsigned short current_base = 0;
struct Scsi_Host *instance;
else
for (; !io_port && (current_base < NO_BASES); ++current_base) {
#if (PDEBUG & PDEBUG_INIT)
- printk("scsi%d : probing io_port %04x\n", hostno, (unsigned int) bases[current_base].io_port);
+ printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
#endif
if ( !bases[current_base].noauto &&
pas16_hw_detect( current_base ) ){
io_port = bases[current_base].io_port;
init_board( io_port, default_irqs[ current_base ] );
#if (PDEBUG & PDEBUG_INIT)
- printk("scsi%d : detected board.\n", hostno);
+ printk("scsi-pas16 : detected board.\n");
#endif
}
}
#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
- printk("scsi%d : io_port = %04x\n", hostno, (unsigned int) io_port);
+ printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
#endif
if (!io_port)
break;
- instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
+ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
instance->io_port = io_port;
NCR5380_init(instance);
if (instance->irq != IRQ_NONE)
if (irqaction (instance->irq, &pas16_sigaction)) {
printk("scsi%d : IRQ%d not free, interrupts disabled\n",
- hostno, instance->irq);
+ instance->host_no, instance->irq);
instance->irq = IRQ_NONE;
}
if (instance->irq == IRQ_NONE) {
- printk("scsi%d : interrupts not enabled. for better interactive performance,\n", hostno);
- printk("scsi%d : please jumper the board for a free IRQ.\n", hostno);
+ printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+ printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
- printk("scsi%d : irq = %d\n", hostno, instance->irq);
+ printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
printk("scsi%d : at 0x%04x", instance->host_no, (int)
++current_override;
++count;
- ++hostno;
}
return count;
}
#ifndef ASM
int pas16_abort(Scsi_Cmnd *);
int pas16_biosparam(Disk *, int, int*);
-int pas16_detect(int);
+int pas16_detect(Scsi_Host_Template *);
const char *pas16_info(void);
int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int pas16_reset(Scsi_Cmnd *);
#ifdef HOSTS_C
-#define MV_PAS16 {"Pro Audio Spectrum-16 SCSI", pas16_detect, pas16_info,\
+#define MV_PAS16 {NULL, "Pro Audio Spectrum-16 SCSI", \
+ pas16_detect, NULL, pas16_info, \
NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL, \
pas16_biosparam, \
/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
+#include <linux/malloc.h>
#include <asm/irq.h>
#include "../block/blk.h"
static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};
-/* We make this not static so that we can read the array with gdb. */
-/* static */ Scsi_Cmnd * last_cmnd = NULL;
+/* This variable is merely a hook so that we can debug the kernel with gdb. */
+Scsi_Cmnd * last_cmnd = NULL;
/*
* As the scsi do command functions are inteligent, and may need to
* devices to the disk driver.
*/
-static void scan_scsis (void)
+static void scan_scsis (struct Scsi_Host * shpnt)
{
int dev, lun, type;
unsigned char scsi_cmd [12];
unsigned char scsi_result [256];
- struct Scsi_Host * shpnt;
+ Scsi_Device * SDpnt;
Scsi_Cmnd SCmd;
++in_scan;
lun = 0;
-
+ type = -1;
SCmd.next = NULL;
SCmd.prev = NULL;
- for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
- {
- shpnt->host_queue = &SCmd; /* We need this so that
+ SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device));
+
+ shpnt->host_queue = &SCmd; /* We need this so that
commands can time out */
- for (dev = 0; dev < 8; ++dev)
- if (shpnt->this_id != dev)
+ for (dev = 0; dev < 8; ++dev)
+ if (shpnt->this_id != dev)
/*
* We need the for so our continue, etc. work fine.
*/
- for (lun = 0; lun < max_scsi_luns; ++lun)
- {
- scsi_devices[NR_SCSI_DEVICES].host = shpnt;
- scsi_devices[NR_SCSI_DEVICES].id = dev;
- scsi_devices[NR_SCSI_DEVICES].lun = lun;
- scsi_devices[NR_SCSI_DEVICES].index = NR_SCSI_DEVICES;
- scsi_devices[NR_SCSI_DEVICES].device_wait = NULL;
+ for (lun = 0; lun < max_scsi_luns; ++lun)
+ {
+ SDpnt->host = shpnt;
+ SDpnt->id = dev;
+ SDpnt->lun = lun;
+ SDpnt->device_wait = NULL;
+ SDpnt->next = NULL;
/*
* Assume that the device will have handshaking problems, and then
* fix this field later if it turns out it doesn't.
*/
- scsi_devices[NR_SCSI_DEVICES].borken = 1;
-
- scsi_cmd[0] = TEST_UNIT_READY;
- scsi_cmd[1] = lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
- scsi_cmd[4] = 0;
-
- SCmd.host = shpnt;
- SCmd.target = dev;
- SCmd.lun = lun;
-
- SCmd.request.dev = 0xffff; /* Mark not busy */
- SCmd.use_sg = 0;
- SCmd.old_use_sg = 0;
- SCmd.transfersize = 0;
- SCmd.underflow = 0;
- SCmd.index = NR_SCSI_DEVICES;
-
- scsi_do_cmd (&SCmd,
- (void *) scsi_cmd, (void *)
- scsi_result, 256, scan_scsis_done,
- SCSI_TIMEOUT + 400, 5);
-
- while (SCmd.request.dev != 0xfffe);
+ SDpnt->borken = 1;
+
+ scsi_cmd[0] = TEST_UNIT_READY;
+ scsi_cmd[1] = lun << 5;
+ scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
+ scsi_cmd[4] = 0;
+
+ SCmd.host = shpnt;
+ SCmd.target = dev;
+ SCmd.lun = lun;
+
+ SCmd.request.dev = 0xffff; /* Mark not busy */
+ SCmd.use_sg = 0;
+ SCmd.old_use_sg = 0;
+ SCmd.transfersize = 0;
+ SCmd.underflow = 0;
+
+ scsi_do_cmd (&SCmd,
+ (void *) scsi_cmd, (void *)
+ scsi_result, 256, scan_scsis_done,
+ SCSI_TIMEOUT + 400, 5);
+
+ while (SCmd.request.dev != 0xfffe);
#if defined(DEBUG) || defined(DEBUG_INIT)
- printk("scsi: scan SCSIS id %d lun %d\n", dev, lun);
- printk("scsi: return code %08x\n", SCmd.result);
+ printk("scsi: scan SCSIS id %d lun %d\n", dev, lun);
+ printk("scsi: return code %08x\n", SCmd.result);
#endif
-
-
- if(SCmd.result) {
- if ((driver_byte(SCmd.result) & DRIVER_SENSE) &&
- ((SCmd.sense_buffer[0] & 0x70) >> 4) == 7) {
- if (SCmd.sense_buffer[2] &0xe0)
- continue; /* No devices here... */
- if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
- ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
- continue;
- }
- else
- break;
- };
-
+
+
+ if(SCmd.result) {
+ if ((driver_byte(SCmd.result) & DRIVER_SENSE) &&
+ ((SCmd.sense_buffer[0] & 0x70) >> 4) == 7) {
+ if (SCmd.sense_buffer[2] &0xe0)
+ continue; /* No devices here... */
+ if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
+ ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
+ continue;
+ }
+ else
+ break;
+ };
+
#if defined (DEBUG) || defined(DEBUG_INIT)
- printk("scsi: performing INQUIRY\n");
+ printk("scsi: performing INQUIRY\n");
#endif
-
- /*
- * Build an INQUIRY command block.
- */
-
- scsi_cmd[0] = INQUIRY;
- scsi_cmd[1] = (lun << 5) & 0xe0;
- scsi_cmd[2] = 0;
- scsi_cmd[3] = 0;
- scsi_cmd[4] = 255;
- scsi_cmd[5] = 0;
-
- SCmd.request.dev = 0xffff; /* Mark not busy */
-
- scsi_do_cmd (&SCmd,
- (void *) scsi_cmd, (void *)
- scsi_result, 256, scan_scsis_done,
- SCSI_TIMEOUT, 3);
-
- while (SCmd.request.dev != 0xfffe);
-
- the_result = SCmd.result;
-
+
+ /*
+ * Build an INQUIRY command block.
+ */
+
+ scsi_cmd[0] = INQUIRY;
+ scsi_cmd[1] = (lun << 5) & 0xe0;
+ scsi_cmd[2] = 0;
+ scsi_cmd[3] = 0;
+ scsi_cmd[4] = 255;
+ scsi_cmd[5] = 0;
+
+ SCmd.request.dev = 0xffff; /* Mark not busy */
+
+ scsi_do_cmd (&SCmd,
+ (void *) scsi_cmd, (void *)
+ scsi_result, 256, scan_scsis_done,
+ SCSI_TIMEOUT, 3);
+
+ while (SCmd.request.dev != 0xfffe);
+
+ the_result = SCmd.result;
+
#if defined(DEBUG) || defined(DEBUG_INIT)
- if (!the_result)
- printk("scsi: INQUIRY successful\n");
- else
- printk("scsi: INQUIRY failed with code %08x\n");
+ if (!the_result)
+ printk("scsi: INQUIRY successful\n");
+ else
+ printk("scsi: INQUIRY failed with code %08x\n");
#endif
-
- if(the_result) break;
-
- /* skip other luns on this device */
-
- if (!the_result)
- {
- scsi_devices[NR_SCSI_DEVICES].
- removable = (0x80 &
- scsi_result[1]) >> 7;
- scsi_devices[NR_SCSI_DEVICES].lockable =
- scsi_devices[NR_SCSI_DEVICES].removable;
- scsi_devices[NR_SCSI_DEVICES].
- changed = 0;
- scsi_devices[NR_SCSI_DEVICES].
- access_count = 0;
- scsi_devices[NR_SCSI_DEVICES].
- busy = 0;
+
+ if(the_result) break;
+
+ /* skip other luns on this device */
+
+ if (!the_result)
+ {
+ SDpnt->removable = (0x80 &
+ scsi_result[1]) >> 7;
+ SDpnt->lockable = SDpnt->removable;
+ SDpnt->changed = 0;
+ SDpnt->access_count = 0;
+ SDpnt->busy = 0;
/*
* Currently, all sequential devices are assumed to be tapes,
* all random devices disk, with the appropriate read only
* flags set for ROM / WORM treated as RO.
*/
- switch (type = scsi_result[0])
- {
- case TYPE_TAPE :
- case TYPE_DISK :
- case TYPE_MOD :
- scsi_devices[NR_SCSI_DEVICES].writeable = 1;
- break;
- case TYPE_WORM :
- case TYPE_ROM :
- scsi_devices[NR_SCSI_DEVICES].writeable = 0;
- break;
- default :
+ switch (type = scsi_result[0])
+ {
+ case TYPE_TAPE :
+ case TYPE_DISK :
+ case TYPE_MOD :
+ SDpnt->writeable = 1;
+ break;
+ case TYPE_WORM :
+ case TYPE_ROM :
+ SDpnt->writeable = 0;
+ break;
+ default :
#if 0
#ifdef DEBUG
- printk("scsi: unknown type %d\n", type);
- print_inquiry(scsi_result);
+ printk("scsi: unknown type %d\n", type);
+ print_inquiry(scsi_result);
#endif
#endif
- type = -1;
- }
-
- scsi_devices[NR_SCSI_DEVICES].soft_reset =
- (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
- scsi_devices[NR_SCSI_DEVICES].random =
- (type == TYPE_TAPE) ? 0 : 1;
- scsi_devices[NR_SCSI_DEVICES].type = type;
-
- if (type != -1)
- {
- print_inquiry(scsi_result);
- switch(type){
- case TYPE_TAPE:
- printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", MAX_ST,
- shpnt->host_no , dev, lun);
- if(NR_ST != -1) ++MAX_ST;
- break;
- case TYPE_ROM:
- printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", MAX_SR,
- shpnt->host_no , dev, lun);
- if(NR_SR != -1) ++MAX_SR;
- break;
- case TYPE_DISK:
- case TYPE_MOD:
- printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 'a'+MAX_SD,
- shpnt->host_no , dev, lun);
- if(NR_SD != -1) ++MAX_SD;
- break;
- default:
- break;
- };
-
- if(NR_SG != -1) ++MAX_SG;
-
- scsi_devices[NR_SCSI_DEVICES].scsi_level =
- scsi_result[2] & 0x07;
- if (scsi_devices[NR_SCSI_DEVICES].scsi_level >= 2 ||
- (scsi_devices[NR_SCSI_DEVICES].scsi_level == 1 &&
- (scsi_result[3] & 0x0f) == 1))
- scsi_devices[NR_SCSI_DEVICES].scsi_level++;
+ type = -1;
+ }
+
+ SDpnt->soft_reset =
+ (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
+ SDpnt->random = (type == TYPE_TAPE) ? 0 : 1;
+ SDpnt->type = type;
+
+ if (type != -1)
+ {
+ print_inquiry(scsi_result);
+ switch(type){
+ case TYPE_TAPE:
+ printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", MAX_ST,
+ shpnt->host_no , dev, lun);
+ if(NR_ST != -1) ++MAX_ST;
+ break;
+ case TYPE_ROM:
+ printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", MAX_SR,
+ shpnt->host_no , dev, lun);
+ if(NR_SR != -1) ++MAX_SR;
+ break;
+ case TYPE_DISK:
+ case TYPE_MOD:
+ printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 'a'+MAX_SD,
+ shpnt->host_no , dev, lun);
+ if(NR_SD != -1) ++MAX_SD;
+ break;
+ default:
+ break;
+ };
+
+ if(NR_SG != -1) ++MAX_SG;
+
+ SDpnt->scsi_level = scsi_result[2] & 0x07;
+ if (SDpnt->scsi_level >= 2 ||
+ (SDpnt->scsi_level == 1 &&
+ (scsi_result[3] & 0x0f) == 1))
+ SDpnt->scsi_level++;
/*
* Set the tagged_queue flag for SCSI-II devices that purport to support
* tagged queuing in the INQUIRY data.
*/
-
- scsi_devices[NR_SCSI_DEVICES].tagged_queue = 0;
-
- if ((scsi_devices[NR_SCSI_DEVICES].scsi_level >= SCSI_2) &&
- (scsi_result[7] & 2)) {
- scsi_devices[NR_SCSI_DEVICES].tagged_supported = 1;
- scsi_devices[NR_SCSI_DEVICES].current_tag = 0;
- }
-
+
+ SDpnt->tagged_queue = 0;
+
+ if ((SDpnt->scsi_level >= SCSI_2) &&
+ (scsi_result[7] & 2)) {
+ SDpnt->tagged_supported = 1;
+ SDpnt->current_tag = 0;
+ }
+
/*
* Accomodate drivers that want to sleep when they should be in a polling
* loop.
*/
- scsi_devices[NR_SCSI_DEVICES].disconnect = 0;
+ SDpnt->disconnect = 0;
/*
* Some revisions of the Texel CD ROM drives have handshaking
* a TEXEL drive.
*/
- if(strncmp("TEXEL", (char *) &scsi_result[8], 5) != 0 ||
- strncmp("CD-ROM", (char *) &scsi_result[16], 6) != 0
+ if(strncmp("TEXEL", (char *) &scsi_result[8], 5) != 0 ||
+ strncmp("CD-ROM", (char *) &scsi_result[16], 6) != 0
/*
* XXX 1.06 has problems, some one should figure out the others too so
* ALL TEXEL drives don't suffer in performance, especially when I finish
*/
#ifdef notyet
- || (strncmp("1.06", (char *) &scsi_result[[, 4) != 0)
+ || (strncmp("1.06", (char *) &scsi_result[[, 4) != 0)))
#endif
- )
- scsi_devices[NR_SCSI_DEVICES].borken = 0;
-
-
- /* These devices need this "key" to unlock the device
- so we can use it */
- if(memcmp("INSITE", &scsi_result[8], 6) == 0 &&
- (memcmp("Floptical F*8I", &scsi_result[16], 16) == 0
- || memcmp("I325VM", &scsi_result[16], 6) == 0)) {
- printk("Unlocked floptical drive.\n");
- scsi_devices[NR_SCSI_DEVICES].lockable = 0;
- scsi_cmd[0] = MODE_SENSE;
- scsi_cmd[1] = (lun << 5) & 0xe0;
- scsi_cmd[2] = 0x2e;
- scsi_cmd[3] = 0;
- scsi_cmd[4] = 0x2a;
- scsi_cmd[5] = 0;
-
- SCmd.request.dev = 0xffff; /* Mark not busy */
-
- scsi_do_cmd (&SCmd,
- (void *) scsi_cmd, (void *)
- scsi_result, 0x2a, scan_scsis_done,
- SCSI_TIMEOUT, 3);
-
- while (SCmd.request.dev != 0xfffe);
- };
-
- ++NR_SCSI_DEVICES;
- /* Some scsi devices cannot be polled for lun != 0
- due to firmware bugs */
- if(blacklisted(scsi_result)) break;
- /* Old drives like the MAXTOR XT-3280 say vers=0 */
- if ((scsi_result[2] & 0x07) == 0)
- break;
- /* Some scsi-1 peripherals do not handle lun != 0.
- I am assuming that scsi-2 peripherals do better */
- if((scsi_result[2] & 0x07) == 1 &&
- (scsi_result[3] & 0x0f) == 0) break;
- }
- } /* if result == DID_OK ends */
- } /* for lun ends */
- shpnt->host_queue = NULL; /* No longer needed here */
- } /* if present */
+ )
+ SDpnt->borken = 0;
+
+
+ /* These devices need this "key" to unlock the device
+ so we can use it */
+ if(memcmp("INSITE", &scsi_result[8], 6) == 0 &&
+ (memcmp("Floptical F*8I", &scsi_result[16], 16) == 0
+ || memcmp("I325VM", &scsi_result[16], 6) == 0)) {
+ printk("Unlocked floptical drive.\n");
+ SDpnt->lockable = 0;
+ scsi_cmd[0] = MODE_SENSE;
+ scsi_cmd[1] = (lun << 5) & 0xe0;
+ scsi_cmd[2] = 0x2e;
+ scsi_cmd[3] = 0;
+ scsi_cmd[4] = 0x2a;
+ scsi_cmd[5] = 0;
+
+ SCmd.request.dev = 0xffff; /* Mark not busy */
+
+ scsi_do_cmd (&SCmd,
+ (void *) scsi_cmd, (void *)
+ scsi_result, 0x2a, scan_scsis_done,
+ SCSI_TIMEOUT, 3);
+
+ while (SCmd.request.dev != 0xfffe);
+ };
+ SDpnt->next = scsi_devices;
+ scsi_devices = SDpnt;
+ ++NR_SCSI_DEVICES;
+ SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof (Scsi_Device));
+ /* Some scsi devices cannot be polled for lun != 0
+ due to firmware bugs */
+ if(blacklisted(scsi_result)) break;
+ /* Old drives like the MAXTOR XT-3280 say vers=0 */
+ if ((scsi_result[2] & 0x07) == 0)
+ break;
+ /* Some scsi-1 peripherals do not handle lun != 0.
+ I am assuming that scsi-2 peripherals do better */
+ if((scsi_result[2] & 0x07) == 1 &&
+ (scsi_result[3] & 0x0f) == 0) break;
+ }
+ } /* if result == DID_OK ends */
+ } /* for lun ends */
+ shpnt->host_queue = NULL; /* No longer needed here */
printk("scsi : detected ");
if(NR_SD != -1)
printk("%d SCSI disk%s ", MAX_SD, (MAX_SD != 1) ? "s" : "");
-
+
if(NR_ST != -1)
printk("%d tape%s ", MAX_ST, (MAX_ST != 1) ? "s" : "");
-
+
if(NR_SR != -1)
printk("%d CD-ROM drive%s ", MAX_SR, (MAX_SR != 1) ? "s" : "");
-
+
printk("total.\n");
+
+ /* Last device block does not exist. Free memory. */
+ scsi_init_free((char *) SDpnt, sizeof(Scsi_Device));
+
in_scan = 0;
} /* scan_scsis ends */
turned off when entering the routine. It is the responsibility
of the calling code to ensure that this is the case. */
-Scsi_Cmnd * request_queueable (struct request * req, int index)
+Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device)
{
Scsi_Cmnd * SCpnt = NULL;
int tablesize;
struct buffer_head * bh, *bhp;
- if ((index < 0) || (index > NR_SCSI_DEVICES))
- panic ("Index number in allocate_device() is out of range.\n");
+ if (!device)
+ panic ("No device passed to allocate_device().\n");
if (req && req->dev <= 0)
panic("Invalid device in allocate_device");
- SCpnt = scsi_devices[index].host->host_queue;
+ SCpnt = device->host->host_queue;
while(SCpnt){
- if(SCpnt->target == scsi_devices[index].id &&
- SCpnt->lun == scsi_devices[index].lun)
+ if(SCpnt->target == device->id &&
+ SCpnt->lun == device->lun)
if(SCpnt->request.dev < 0) break;
SCpnt = SCpnt->next;
};
if (!SCpnt) return NULL;
- if (scsi_devices[index].host->hostt->can_queue
- && scsi_devices[index].host->host_busy >= scsi_devices[index].host->hostt->can_queue) return NULL;
+ if (device->host->hostt->can_queue
+ && device->host->host_busy >= device->host->hostt->can_queue) return NULL;
if (req) {
memcpy(&SCpnt->request, req, sizeof(struct request));
- tablesize = scsi_devices[index].host->sg_tablesize;
+ tablesize = device->host->sg_tablesize;
bhp = bh = req->bh;
if(!tablesize) bh = NULL;
/* Take a quick look through the table to see how big it is. We already
request_queueable function also knows the internal allocation scheme
of the packets for each device */
-Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
+Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device,
+ int wait)
{
int dev = -1;
struct request * req = NULL;
Scsi_Cmnd * SCpnt = NULL;
Scsi_Cmnd * SCwait = NULL;
- if ((index < 0) || (index > NR_SCSI_DEVICES))
- panic ("Index number in allocate_device() is out of range.\n");
+ if (!device)
+ panic ("No device passed to allocate_device().\n");
if (reqp) req = *reqp;
/* See if this request has already been queued by an interrupt routine */
if (req && (dev = req->dev) <= 0) return NULL;
- host = scsi_devices[index].host;
+ host = device->host;
while (1==1){
SCpnt = host->host_queue;
while(SCpnt){
- if(SCpnt->target == scsi_devices[index].id &&
- SCpnt->lun == scsi_devices[index].lun) {
+ if(SCpnt->target == device->id &&
+ SCpnt->lun == device->lun) {
SCwait = SCpnt;
if(SCpnt->request.dev < 0) break;
};
sti();
if(!wait) return NULL;
if (!SCwait) {
- printk("Attempt to allocate device index %d, target %d, lun %d\n",
- index, scsi_devices[index].id ,scsi_devices[index].lun);
+ printk("Attempt to allocate device target %d, lun %d\n",
+ device->id ,device->lun);
panic("No device found in allocate_device\n");
};
- SCSI_SLEEP(&scsi_devices[SCwait->index].device_wait,
+ SCSI_SLEEP(&device->device_wait,
(SCwait->request.dev > 0));
} else {
if (req) {
memcpy(&SCpnt->request, req, sizeof(struct request));
- tablesize = scsi_devices[index].host->sg_tablesize;
+ tablesize = device->host->sg_tablesize;
bhp = bh = req->bh;
if(!tablesize) bh = NULL;
/* Take a quick look through the table to see how big it is. We already
case NO_SENSE:
return 0;
case RECOVERED_ERROR:
- if (scsi_devices[SCpnt->index].type == TYPE_TAPE)
+ if (SCpnt->device->type == TYPE_TAPE)
return SUGGEST_IS_OK;
else
return 0;
return 0;
}
+
+/* These are special functions that can be used to obtain memory at boot time.
+ They act line a malloc function, but they simply take memory from the
+ pool */
+
+static unsigned int scsi_init_memory_start = 0;
+int scsi_loadable_module_flag; /* Set after we scan builtin drivers */
+
+void * scsi_init_malloc(unsigned int size)
+{
+ unsigned int retval;
+ if(scsi_loadable_module_flag) {
+ retval = (unsigned int) kmalloc(size, GFP_ATOMIC);
+ } else {
+ retval = scsi_init_memory_start;
+ scsi_init_memory_start += size;
+ }
+ return (void *) retval;
+}
+
+
+void scsi_init_free(char * ptr, unsigned int size)
+{ /* FIXME - not right. We need to comare addresses to see whether this was
+ kmalloc'd or not */
+ if((unsigned int) ptr < scsi_loadable_module_flag) {
+ kfree(ptr);
+ } else {
+ if(((unsigned int) ptr) + size == scsi_init_memory_start)
+ scsi_init_memory_start = (unsigned int) ptr;
+ }
+}
+
/*
scsi_dev_init() is our initialization routine, which inturn calls host
initialization, bus scanning, and sd/st initialization routines. It
unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end)
{
- int i;
- struct Scsi_Host * host;
+ struct Scsi_Host * host = NULL;
+ Scsi_Device * SDpnt;
+ struct Scsi_Host * shpnt;
Scsi_Cmnd * SCpnt;
#ifdef FOO_ON_YOU
return;
#endif
+
+ /* Init a few things so we can "malloc" memory. */
+ scsi_loadable_module_flag = 0;
+ scsi_init_memory_start = memory_start;
+
timer_table[SCSI_TIMER].fn = scsi_main_timeout;
timer_table[SCSI_TIMER].expires = 0;
/* initialize all hosts */
- memory_start = scsi_init(memory_start, memory_end);
+ scsi_init();
- scsi_devices = (Scsi_Device *) memory_start;
- scan_scsis(); /* scan for scsi devices */
- memory_start += NR_SCSI_DEVICES * sizeof(Scsi_Device);
-
- memory_start = sd_init1(memory_start, memory_end);
- memory_start = st_init1(memory_start, memory_end);
- memory_start = sr_init1(memory_start, memory_end);
- memory_start = sg_init1(memory_start, memory_end);
+ scsi_devices = (Scsi_Device *) NULL;
- last_cmnd = (Scsi_Cmnd *) memory_start;
+ for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
+ scan_scsis(shpnt); /* scan for scsi devices */
- SCpnt = last_cmnd;
+ sd_init1();
+ st_init1();
+ sr_init1();
+ sg_init1();
- for (i=0; i< NR_SCSI_DEVICES; i++) {
+ for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
int j;
- scsi_devices[i].scsi_request_fn = NULL;
- switch (scsi_devices[i].type)
+ SDpnt->scsi_request_fn = NULL;
+ switch (SDpnt->type)
{
case TYPE_TAPE :
- st_attach(&scsi_devices[i]);
+ st_attach(SDpnt);
break;
case TYPE_ROM:
- sr_attach(&scsi_devices[i]);
+ sr_attach(SDpnt);
break;
case TYPE_DISK:
case TYPE_MOD:
- sd_attach(&scsi_devices[i]);
+ sd_attach(SDpnt);
default:
break;
};
- sg_attach(&scsi_devices[i]);
- if(scsi_devices[i].type != -1){
- for(j=0;j<scsi_devices[i].host->hostt->cmd_per_lun;j++){
- SCpnt->host = scsi_devices[i].host;
- SCpnt->device = &scsi_devices[i];
- SCpnt->target = scsi_devices[i].id;
- SCpnt->lun = scsi_devices[i].lun;
- SCpnt->index = i;
+ sg_attach(SDpnt);
+ if(SDpnt->type != -1){
+ for(j=0;j<SDpnt->host->hostt->cmd_per_lun;j++){
+ SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd));
+ SCpnt->host = SDpnt->host;
+ SCpnt->device = SDpnt;
+ SCpnt->target = SDpnt->id;
+ SCpnt->lun = SDpnt->lun;
SCpnt->request.dev = -1; /* Mark not busy */
SCpnt->use_sg = 0;
SCpnt->old_use_sg = 0;
SCpnt->underflow = 0;
SCpnt->transfersize = 0;
SCpnt->host_scribble = NULL;
- host = scsi_devices[i].host;
+ host = SDpnt->host;
if(host->host_queue)
host->host_queue->prev = SCpnt;
SCpnt->next = host->host_queue;
SCpnt->prev = NULL;
host->host_queue = SCpnt;
- SCpnt++;
};
};
};
- memory_start = (int) SCpnt;
-
+ memory_start = scsi_init_memory_start;
if (NR_SD > 0 || NR_SR > 0 || NR_ST > 0)
dma_sectors = 16; /* Base value we use */
- for (i = 0; i < NR_SCSI_DEVICES; ++i) {
- struct Scsi_Host * host;
- host = scsi_devices[i].host;
+ for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
+ host = SDpnt->host;
- if(scsi_devices[i].type != TYPE_TAPE)
+ if(SDpnt->type != TYPE_TAPE)
dma_sectors += ((host->sg_tablesize *
sizeof(struct scatterlist) + 511) >> 9) *
host->hostt->cmd_per_lun;
if(host->unchecked_isa_dma &&
memory_end > ISA_DMA_THRESHOLD &&
- scsi_devices[i].type != TYPE_TAPE) {
+ SDpnt->type != TYPE_TAPE) {
dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
host->hostt->cmd_per_lun;
need_isa_buffer++;
memory_start = sr_init(memory_start, memory_end); /* init scsi CDROMs */
memory_start = sg_init(memory_start, memory_end); /* init scsi generic */
+ scsi_loadable_module_flag = 1;
return memory_start;
}
scsi_dump_status(void)
{
int i, i1;
+ Scsi_Host * shpnt;
Scsi_Cmnd * SCpnt;
printk("Dump of scsi parameters:\n");
- SCpnt = last_cmnd;
- for(i=0; i<NR_SCSI_DEVICES; i++)
- for(i1=0; i1<scsi_devices[i].host->hostt->cmd_per_lun;i1++)
+ for(shpnt = scsi_hosts; shpnt; shpnt = shpnt->next)
+ for(SCpnt=shpnt->host_queue; SCpnt; SCpnt = SCpnt->next)
{
/* (0) 0:0:0 (802 123434 8 8 0) (3 3 2) (%d %d %d) %d %x */
printk("(%d) %d:%d:%d (%4.4x %d %d %d %d) (%d %d %x) (%d %d %d) %x %x %d %x\n",
(SCpnt->request.waiting ?
SCpnt->request.waiting->pid : 0),
SCpnt->result);
- SCpnt++;
};
printk("wait_for_request = %x\n", wait_for_request);
/* Now dump the request lists for each block device */
}
}
#endif
+
+
*/
typedef struct scsi_device {
- unsigned char id, lun, index;
+ struct scsi_device * next; /* Used for linked list */
+ unsigned char id, lun;
int access_count; /* Count of open channels/mounts */
struct wait_queue * device_wait; /* Used to wait if device is busy */
struct Scsi_Host * host;
typedef struct scsi_cmnd {
struct Scsi_Host * host;
Scsi_Device * device;
- unsigned char target, lun, index;
+ unsigned char target, lun;
struct scsi_cmnd *next, *prev;
/* These elements define the operation we are about to perform */
int timeout, int retries);
-extern Scsi_Cmnd * allocate_device(struct request **, int, int);
+extern Scsi_Cmnd * allocate_device(struct request **, Scsi_Device *, int);
-extern Scsi_Cmnd * request_queueable(struct request *, int);
+extern Scsi_Cmnd * request_queueable(struct request *, Scsi_Device *);
extern int scsi_reset (Scsi_Cmnd *);
extern int max_scsi_hosts;
extern int MAX_SD, NR_SD, MAX_ST, NR_ST, MAX_SR, NR_SR, NR_SG, MAX_SG;
extern unsigned long sd_init(unsigned long, unsigned long);
-extern unsigned long sd_init1(unsigned long, unsigned long);
+extern void sd_init1(void);
extern void sd_attach(Scsi_Device *);
extern unsigned long sr_init(unsigned long, unsigned long);
-extern unsigned long sr_init1(unsigned long, unsigned long);
+extern void sr_init1(void);
extern void sr_attach(Scsi_Device *);
extern unsigned long st_init(unsigned long, unsigned long);
-extern unsigned long st_init1(unsigned long, unsigned long);
+extern void st_init1(void);
extern void st_attach(Scsi_Device *);
extern unsigned long sg_init(unsigned long, unsigned long);
-extern unsigned long sg_init1(unsigned long, unsigned long);
+extern void sg_init1(void);
extern void sg_attach(Scsi_Device *);
#if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
need_resched = 1;
}
req->dev = -1;
- wake_up(&scsi_devices[SCpnt->index].device_wait);
+ wake_up(&SCpnt->device->device_wait);
return;
}
#endif
#define SCSI_SLEEP(QUEUE, CONDITION) { \
+ long old_state; \
if (CONDITION) { \
- struct wait_queue wait = { current, NULL}; \
+ struct wait_queue wait = { current, NULL}; \
add_wait_queue(QUEUE, &wait); \
sleep_repeat: \
+ old_state = current->state; \
current->state = TASK_UNINTERRUPTIBLE; \
if (CONDITION) { \
schedule(); \
goto sleep_repeat; \
} \
remove_wait_queue(QUEUE, &wait); \
- current->state = TASK_RUNNING; \
+ if (current->state == TASK_UNINTERRUPTIBLE) \
+ current->state = old_state; \
}; }
#endif
#endif
static volatile void (*do_done[SCSI_DEBUG_MAILBOXES])(Scsi_Cmnd *) = {NULL, };
-static int scsi_debug_host = 0;
extern void scsi_debug_interrupt();
volatile Scsi_Cmnd * SCint[SCSI_DEBUG_MAILBOXES] = {NULL,};
}
-int scsi_debug_detect(int hostnum)
+int scsi_debug_detect(Scsi_Host_Template * tpnt)
{
- scsi_debug_host = hostnum;
#ifndef IMMEDIATE
timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle;
timer_table[SCSI_DEBUG_TIMER].expires = 0;
int j;
void (*my_done)(Scsi_Cmnd *);
DEB(printk("scsi_debug_abort\n"));
- SCpnt->result = i << 16;
+ SCpnt->result = SCpnt->abort_reason << 16;
for(j=0;j<SCSI_DEBUG_MAILBOXES; j++) {
if(SCpnt == SCint[j]) {
my_done = do_done[j];
#include <linux/types.h>
-int scsi_debug_detect(int);
+int scsi_debug_detect(Scsi_Host_Template *);
int scsi_debug_command(Scsi_Cmnd *);
int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int scsi_debug_abort(Scsi_Cmnd *, int);
+int scsi_debug_abort(Scsi_Cmnd *);
int scsi_debug_biosparam(Disk *, int, int[]);
const char *scsi_debug_info(void);
int scsi_debug_reset(Scsi_Cmnd *);
#define SCSI_DEBUG_MAILBOXES 8
-#define SCSI_DEBUG {"SCSI DEBUG", scsi_debug_detect, \
+#define SCSI_DEBUG {NULL, "SCSI DEBUG", scsi_debug_detect, NULL, \
scsi_debug_info, scsi_debug_command, \
scsi_debug_queuecommand, \
scsi_debug_abort, \
int result;
Scsi_Cmnd * SCpnt;
- SCpnt = allocate_device(NULL, dev->index, 1);
+ SCpnt = allocate_device(NULL, dev, 1);
scsi_do_cmd(SCpnt, cmd, NULL, 0,
scsi_ioctl_done, MAX_TIMEOUT,
MAX_RETRIES);
result = SCpnt->result;
SCpnt->request.dev = -1;
- wake_up(&scsi_devices[SCpnt->index].device_wait);
+ wake_up(&SCpnt->device->device_wait);
return result;
}
#ifndef DEBUG_NO_CMD
- SCpnt = allocate_device(NULL, dev->index, 1);
+ SCpnt = allocate_device(NULL, dev, 1);
scsi_do_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, MAX_TIMEOUT,
MAX_RETRIES);
SCpnt->request.dev = -1; /* Mark as not busy */
if (buf) scsi_free(buf, buf_needed);
- if(scsi_devices[SCpnt->index].scsi_request_fn)
- (*scsi_devices[SCpnt->index].scsi_request_fn)();
+ if(SCpnt->device->scsi_request_fn)
+ (*SCpnt->device->scsi_request_fn)();
- wake_up(&scsi_devices[SCpnt->index].device_wait);
+ wake_up(&SCpnt->device->device_wait);
return result;
#else
{
{
char scsi_cmd[12];
- if ((cmd != 0 && dev->index > NR_SCSI_DEVICES))
- return -ENXIO;
+ /* No idea how this happens.... */
+ if (!dev) return -ENXIO;
switch (cmd) {
case SCSI_IOCTL_GET_IDLUN:
#define SD_MOD_TIMEOUT 750
#define CLUSTERABLE_DEVICE(SC) (SC->host->hostt->use_clustering && \
- scsi_devices[SC->index].type != TYPE_MOD)
+ SC->device->type != TYPE_MOD)
struct hd_struct * sd;
if (flag++ == 0)
SCpnt = allocate_device(&CURRENT,
- rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
+ rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device, 0);
else SCpnt = NULL;
sti();
req = CURRENT;
while(req){
SCpnt = request_queueable(req,
- rscsi_disks[DEVICE_NR(MINOR(req->dev))].device->index);
+ rscsi_disks[DEVICE_NR(MINOR(req->dev))].device);
if(SCpnt) break;
req1 = req;
req = req->next;
scsi_do_cmd (SCpnt, (void *) cmd, buff,
this_count * rscsi_disks[dev].sector_size,
rw_intr,
- (scsi_devices[SCpnt->index].type == TYPE_DISK ?
+ (SCpnt->device->type == TYPE_DISK ?
SD_TIMEOUT : SD_MOD_TIMEOUT),
MAX_RETRIES);
}
a fatal error, and many devices report such an error just after a scsi
bus reset. */
- SCpnt = allocate_device(NULL, rscsi_disks[i].device->index, 1);
+ SCpnt = allocate_device(NULL, rscsi_disks[i].device, 1);
buffer = (unsigned char *) scsi_malloc(512);
spintime = 0;
};
time1 = jiffies;
- while(jiffies < time1 + 100); /* Wait 1 second for next try */
+ while(jiffies < time1 + HZ); /* Wait 1 second for next try */
printk( "." );
};
} while(the_result && spintime && spintime+5000 > jiffies);
SCpnt->request.dev = -1; /* Mark as not busy */
- wake_up(&scsi_devices[SCpnt->index].device_wait);
+ wake_up(&SCpnt->device->device_wait);
/* Wake up a process waiting for device*/
return memory_start;
}
-unsigned long sd_init1(unsigned long mem_start, unsigned long mem_end){
- rscsi_disks = (Scsi_Disk *) mem_start;
- mem_start += MAX_SD * sizeof(Scsi_Disk);
- return mem_start;
+void sd_init1(){
+ rscsi_disks = (Scsi_Disk *) scsi_init_malloc(MAX_SD * sizeof(Scsi_Disk));
};
void sd_attach(Scsi_Device * SDp){
#endif /* def SLOW_HANDSHAKE */
-int seagate_st0x_detect (int hostnum)
+int seagate_st0x_detect (Scsi_Host_Template * tpnt)
{
+ struct Scsi_Host *instance;
#ifndef OVERRIDE
int i,j;
#endif
#endif /* OVERIDE */
} /* (! controller_type) */
- scsi_hosts[hostnum].this_id = (controller_type == SEAGATE) ? 7 : 6;
+ tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
if (base_address)
{
* At all times, we will use IRQ 5. Should also check for IRQ3 if we
* loose our first interrupt.
*/
- hostno = hostnum;
+ instance = scsi_register(tpnt, 0);
+ hostno = instance->host_no;
if (irqaction((int) irq, &seagate_sigaction)) {
printk("scsi%d : unable to allocate IRQ%d\n",
hostno, (int) irq);
st0x_aborted = 0;
#ifdef SLOW_HANDSHAKE
- borken = (int) scsi_devices[SCint->index].borken;
+ borken = (int) SCint->device->borken;
#endif
#if (DEBUG & PRINT_COMMAND)
$Header
*/
#ifndef ASM
-int seagate_st0x_detect(int);
+int seagate_st0x_detect(Scsi_Host_Template *);
int seagate_st0x_command(Scsi_Cmnd *);
int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int seagate_st0x_biosparam(Disk *, int, int*);
-#define SEAGATE_ST0X {"Seagate ST-01/ST-02", seagate_st0x_detect, \
+#define SEAGATE_ST0X {NULL, "Seagate ST-01/ST-02", seagate_st0x_detect, \
+ NULL, \
seagate_st0x_info, seagate_st0x_command, \
seagate_st0x_queue_command, seagate_st0x_abort, \
seagate_st0x_reset, NULL, seagate_st0x_biosparam, \
#ifdef DEBUG
printk("allocating device\n");
#endif
- if (!(SCpnt=allocate_device(NULL,device->device->index, !(filp->f_flags & O_NONBLOCK))))
+ if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
{
device->pending=0;
wake_up(&device->write_wait);
return mem_start;
}
-unsigned long sg_init1(unsigned long mem_start, unsigned long mem_end)
+void sg_init1()
{
- scsi_generics = (struct scsi_generic *) mem_start;
- mem_start += MAX_SG * sizeof(struct scsi_generic);
- return mem_start;
+ scsi_generics = (struct scsi_generic *)
+ scsi_init_malloc(MAX_SG * sizeof(struct scsi_generic));
};
void sg_attach(Scsi_Device * SDp)
if (flag++ == 0)
SCpnt = allocate_device(&CURRENT,
- scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
+ scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0);
else SCpnt = NULL;
sti();
req = CURRENT;
while(req){
SCpnt = request_queueable(req,
- scsi_CDs[DEVICE_NR(MINOR(req->dev))].device->index);
+ scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
if(SCpnt) break;
req1 = req;
req = req->next;
rw_intr, SR_TIMEOUT, MAX_RETRIES);
}
-unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){
- scsi_CDs = (Scsi_CD *) mem_start;
- mem_start += MAX_SR * sizeof(Scsi_CD);
- return mem_start;
+void sr_init1(){
+ scsi_CDs = (Scsi_CD *) scsi_init_malloc(MAX_SR * sizeof(Scsi_CD));
};
void sr_attach(Scsi_Device * SDp){
int the_result, retries;
Scsi_Cmnd * SCpnt;
- SCpnt = allocate_device(NULL, scsi_CDs[i].device->index, 1);
+ SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
retries = 3;
do {
SCpnt->request.dev = -1; /* Mark as not busy */
- wake_up(&scsi_devices[SCpnt->index].device_wait);
+ wake_up(&SCpnt->device->device_wait);
if (the_result) {
scsi_CDs[i].capacity = 0x1fffff;
Scsi_Cmnd * SCpnt;
int result;
- SCpnt = allocate_device(NULL, scsi_CDs[target].device->index, 1);
+ SCpnt = allocate_device(NULL, scsi_CDs[target].device, 1);
scsi_do_cmd(SCpnt,
(void *) sr_cmd, buffer, buflength, sr_ioctl_done,
IOCTL_TIMEOUT, IOCTL_RETRIES);
result = SCpnt->result;
SCpnt->request.dev = -1; /* Deallocate */
- wake_up(&scsi_devices[SCpnt->index].device_wait);
+ wake_up(&SCpnt->device->device_wait);
/* Wake up a process waiting for device*/
return result;
}
cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
cmd[5] = 0;
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
SCpnt->sense_buffer[0] = 0;
SCpnt->request.dev = dev;
scsi_do_cmd(SCpnt,
result = 0;
if (STp->dirty == 1) {
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
offset = (STp->buffer)->buffer_bytes;
transfer = ((offset + STp->block_size - 1) /
STp->eof_hit = 0;
STp->recover_count = 0;
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
if (!SCpnt) {
printk("st%d: Tape request not allocated", dev);
return (-EBUSY);
#endif
if (result == 0 || result == (-ENOSPC)) {
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
SCpnt->sense_buffer[0] = 0;
memset(cmd, 0, 10);
if (!STp->do_async_writes)
write_threshold--;
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
total = count;
STp->rw = ST_READING;
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
for (total = 0; total < count; ) {
return (-ENOSYS);
}
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
SCpnt->sense_buffer[0] = 0;
SCpnt->request.dev = dev;
scsi_do_cmd(SCpnt,
if (i)
return i;
- SCpnt = allocate_device(NULL, (STp->device)->index, 1);
+ SCpnt = allocate_device(NULL, STp->device, 1);
SCpnt->sense_buffer[0]=0;
memset (scmd, 0, 10);
if(NR_ST > MAX_ST) panic ("scsi_devices corrupt (st)");
};
-unsigned long st_init1(unsigned long mem_start, unsigned long mem_end){
- scsi_tapes = (Scsi_Tape *) mem_start;
- mem_start += MAX_ST * sizeof(Scsi_Tape);
- return mem_start;
+void st_init1(){
+ scsi_tapes = (Scsi_Tape *) scsi_init_malloc(MAX_ST * sizeof(Scsi_Tape));
};
/* Driver initialization */
unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
{
- int i, dev_nbr;
+ int i;
Scsi_Tape * STp;
+ Scsi_Device * SDp;
if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
st_buffer_size, st_write_threshold);
#endif
- for (i=0, dev_nbr=(-1); i < NR_ST; ++i) {
+ for (i=0, SDp = scsi_devices; i < NR_ST; ++i) {
STp = &(scsi_tapes[i]);
STp->capacity = 0xfffff;
STp->dirty = 0;
mem_start += sizeof(struct mtget);
/* Initialize status */
memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
- for (dev_nbr++; dev_nbr < NR_SCSI_DEVICES; dev_nbr++)
- if (scsi_devices[dev_nbr].type == TYPE_TAPE)
+ for (; SDp; SDp = SDp->next)
+ if (SDp->type == TYPE_TAPE)
break;
- if (dev_nbr >= NR_SCSI_DEVICES)
+ if (!SDp)
printk("st%d: ERROR: Not found in scsi chain.\n", i);
else {
- if (scsi_devices[dev_nbr].scsi_level <= 2)
+ if (SDp->scsi_level <= 2)
STp->mt_status->mt_type = MT_ISSCSI1;
else
STp->mt_status->mt_type = MT_ISSCSI2;
}
+ SDp = SDp->next;
}
/* Allocate the buffers */
static struct sigaction t128_sigaction = { t128_intr, 0, SA_INTERRUPT , NULL };
/*
- * Function : int t128_detect(int hostno)
+ * Function : int t128_detect(Scsi_Host_Template * tpnt)
*
* Purpose : detects and initializes T128,T128F, or T228 controllers
* that were autoprobed, overriden on the LILO command line,
* or specified at compile time.
*
- * Inputs : hostno - id of this SCSI adapter.
+ * Inputs : tpnt - template for this SCSI adapter.
*
* Returns : 1 if a host adapter was found, 0 if not.
*
*/
-int t128_detect(int hostno) {
+int t128_detect(Scsi_Host_Template * tpnt) {
static int current_override = 0, current_base = 0;
struct Scsi_Host *instance;
unsigned char *base;
else
for (; !base && (current_base < NO_BASES); ++current_base) {
#if (TDEBUG & TDEBUG_INIT)
- printk("scsi%d : probing address %08x\n", hostno, (unsigned int) bases[current_base].address);
+ printk("scsi : probing address %08x\n", (unsigned int) bases[current_base].address);
#endif
for (sig = 0; sig < NO_SIGNATURES; ++sig)
if (!bases[current_base].noauto && !memcmp
signatures[sig].string, strlen(signatures[sig].string))) {
base = bases[current_base].address;
#if (TDEBUG & TDEBUG_INIT)
- printk("scsi%d : detected board.\n", hostno);
+ printk("scsi-t128 : detected board.\n");
#endif
break;
}
}
#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
- printk("scsi%d : base = %08x\n", hostno, (unsigned int) base);
+ printk("scsi-t128 : base = %08x\n", (unsigned int) base);
#endif
if (!base)
break;
- instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
+ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
instance->base = base;
NCR5380_init(instance);
if (instance->irq != IRQ_NONE)
if (irqaction (instance->irq, &t128_sigaction)) {
printk("scsi%d : IRQ%d not free, interrupts disabled\n",
- hostno, instance->irq);
+ instance->host_no, instance->irq);
instance->irq = IRQ_NONE;
}
if (instance->irq == IRQ_NONE) {
- printk("scsi%d : interrupts not enabled. for better interactive performance,\n", hostno);
- printk("scsi%d : please jumper the board for a free IRQ.\n", hostno);
+ printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+ printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
- printk("scsi%d : irq = %d\n", hostno, instance->irq);
+ printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
#endif
printk("scsi%d : at 0x%08x", instance->host_no, (int)
++current_override;
++count;
- ++hostno;
}
return count;
}
#ifndef ASM
int t128_abort(Scsi_Cmnd *);
int t128_biosparam(Disk *, int, int*);
-int t128_detect(int);
+int t128_detect(Scsi_Host_Template *);
const char *t128_info(void);
int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int t128_reset(Scsi_Cmnd *);
#ifdef HOSTS_C
-#define TRANTOR_T128 {"Trantor T128/T128F/T228", t128_detect, t128_info,\
+#define TRANTOR_T128 {NULL, "Trantor T128/T128F/T228", t128_detect, NULL, \
+ t128_info, \
NULL, t128_queue_command, t128_abort, t128_reset, NULL, \
t128_biosparam, \
/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
volatile int csir_done;
#endif
- /* Our index in the host adapter array maintained by higher-level driver */
- int host_number;
-
/* A pool of MSCP structures for this adapter, and a bitmask of
busy structures. (If ULTRASTOR_14F_MAX_CMDS == 1, a 1 byte
busy flag is used instead.) */
}
#endif
-static int ultrastor_14f_detect(int hostnum)
+static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
{
size_t i;
unsigned char in_byte, version_byte = 0;
config.port_address, config.bios_segment, config.interrupt,
config.dma_channel, config.ha_scsi_id, config.subversion);
#endif
- config.host_number = hostnum;
- scsi_hosts[hostnum].this_id = config.ha_scsi_id;
- scsi_hosts[hostnum].unchecked_isa_dma = (config.subversion != U34F);
+ tpnt->this_id = config.ha_scsi_id;
+ tpnt->unchecked_isa_dma = (config.subversion != U34F);
#if ULTRASTOR_MAX_CMDS > 1
config.mscp_free = ~0;
free_irq(config.interrupt);
return FALSE;
}
- scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_14F_MAX_SG;
+ tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
printk("UltraStor driver version" VERSION ". Using %d SG lists.\n",
ULTRASTOR_14F_MAX_SG);
return TRUE;
}
-static int ultrastor_24f_detect(int hostnum)
+static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
{
register int i;
struct Scsi_Host * shpnt = NULL;
config.port_address, config.bios_segment,
config.interrupt, config.ha_scsi_id);
#endif
- config.host_number = hostnum;
- scsi_hosts[hostnum].this_id = config.ha_scsi_id;
- scsi_hosts[hostnum].unchecked_isa_dma = 0;
- scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_24F_MAX_SG;
+ tpnt->this_id = config.ha_scsi_id;
+ tpnt->unchecked_isa_dma = 0;
+ tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
- shpnt = scsi_register(hostnum, 0);
+ shpnt = scsi_register(tpnt, 0);
shpnt->irq = config.interrupt;
shpnt->dma_channel = config.dma_channel;
shpnt->io_port = config.port_address;
outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
outb(0x02, SYS_DOORBELL_MASK(addr+12));
printk("UltraStor driver version " VERSION ". Using %d SG lists.\n",
- scsi_hosts[hostnum].sg_tablesize);
+ tpnt->sg_tablesize);
return TRUE;
}
return FALSE;
}
-int ultrastor_detect(int hostnum)
+int ultrastor_detect(Scsi_Host_Template * tpnt)
{
- return ultrastor_14f_detect(hostnum) || ultrastor_24f_detect(hostnum);
+ return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
}
const char *ultrastor_info(void)
activity.
??? Which other device types should never use the cache? */
- my_mscp->ca = scsi_devices[SCpnt->index].type != TYPE_TAPE;
+ my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
my_mscp->target_id = SCpnt->target;
my_mscp->ch_no = 0;
my_mscp->lun = SCpnt->lun;
#ifndef _ULTRASTOR_H
#define _ULTRASTOR_H
-int ultrastor_detect(int);
+int ultrastor_detect(Scsi_Host_Template *);
const char *ultrastor_info(void);
int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int ultrastor_abort(Scsi_Cmnd *);
#define ULTRASTOR_24F_PORT 0xC80
-#define ULTRASTOR_14F \
- { "UltraStor 14F/24F/34F", ultrastor_detect, ultrastor_info, 0, \
- ultrastor_queuecommand, ultrastor_abort, ultrastor_reset, \
- 0, ultrastor_biosparam, ULTRASTOR_MAX_CMDS, 0, \
- ULTRASTOR_14F_MAX_SG, ULTRASTOR_MAX_CMDS_PER_LUN, 0, 1, \
- ENABLE_CLUSTERING }
+#define ULTRASTOR_14F { NULL, /* Ptr for modules*/ \
+ "UltraStor 14F/24F/34F", \
+ ultrastor_detect, \
+ NULL, /* Release */ \
+ ultrastor_info, \
+ 0, \
+ ultrastor_queuecommand, \
+ ultrastor_abort, \
+ ultrastor_reset, \
+ 0, \
+ ultrastor_biosparam, \
+ ULTRASTOR_MAX_CMDS, \
+ 0, \
+ ULTRASTOR_14F_MAX_SG, \
+ ULTRASTOR_MAX_CMDS_PER_LUN, \
+ 0, \
+ 1, \
+ ENABLE_CLUSTERING }
#ifdef ULTRASTOR_PRIVATE
*
*/
typedef struct adapter {
- int num; /* Index into Scsi_hosts array */
struct Scsi_Host *sh; /* Pointer to Scsi_Host structure */
int iobase; /* This adapter's I/O base address */
int irq; /* This adapter's IRQ level */
}
-int wd7000_detect(int hostnum)
+int wd7000_detect(Scsi_Host_Template * tpnt)
/*
* Returns the number of adapters this driver is supporting.
*
* Scsi_Host structure (sh), and is located by the empty
* array hostdata.
*/
- sh = scsi_register( hostnum, sizeof(Adapter) );
+ sh = scsi_register(tpnt, sizeof(Adapter) );
host = (Adapter *) sh->hostdata;
#ifdef DEBUG
printk("wd7000_detect: adapter allocated at %06x\n",
(int)host);
#endif
memset( host, 0, sizeof(Adapter) );
- host->num = hostnum; host->sh = sh;
+ host->sh = sh;
host->irq = cfg->irq;
host->iobase = cfg->iobase;
host->dma = cfg->dma;
irq2host[host->irq] = host;
if (!wd7000_init(host)) { /* Initialization failed */
- scsi_unregister( sh, sizeof(Adapter) );
+ scsi_unregister (sh);
continue;
}
#include <linux/types.h>
-int wd7000_detect(int);
+int wd7000_detect(Scsi_Host_Template *);
int wd7000_command(Scsi_Cmnd *);
int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int wd7000_abort(Scsi_Cmnd *);
#define WD7000_Q 16
#define WD7000_SG 16
-#define WD7000 {\
+#define WD7000 { NULL, \
"Western Digital WD-7000", \
wd7000_detect, \
+ NULL, \
wd7000_info, \
wd7000_command, \
wd7000_queuecommand, \
* (C) 1991 Linus Torvalds - minix filesystem
*/
-#include <linux/config.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/iso_fs.h>
#include <asm/system.h>
#include <asm/segment.h>
-#if defined(CONFIG_BLK_DEV_SR)
-extern int check_cdrom_media_change(int, int);
-#endif
-#if defined(CONFIG_CDU31A)
-extern int check_cdu31a_media_change(int, int);
-#endif
-#if defined(CONFIG_MCD)
-extern int check_mcd_media_change(int, int);
-#endif
-
#ifdef LEAK_CHECK
static int check_malloc = 0;
static int check_bread = 0;
#define NFS_READDIR_CACHE_SIZE 64
-#define NFS_MAX_FILE_IO_BUFFER_SIZE 16834
+#define NFS_MAX_FILE_IO_BUFFER_SIZE 16384
#define NFS_DEF_FILE_IO_BUFFER_SIZE 1024
/*
* Pauline Middelink : Pidentd support
* Alan Cox : Make /proc safer.
* Erik Schoenfelder : /proc/net/snmp
+ * Alan Cox : Handle dead sockets properly.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
static int
get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t offset, int length)
{
- struct sock **s_array;
- struct sock *sp;
- int i;
- int timer_active;
- unsigned long dest, src;
- unsigned short destp, srcp;
- int len=0;
- off_t pos=0;
- off_t begin=0;
+ struct sock **s_array;
+ struct sock *sp;
+ int i;
+ int timer_active;
+ unsigned long dest, src;
+ unsigned short destp, srcp;
+ int len=0;
+ off_t pos=0;
+ off_t begin=0;
-
- s_array = pro->sock_array;
- len+=sprintf(buffer, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n");
+ s_array = pro->sock_array;
+ len+=sprintf(buffer, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n");
/*
* This was very pretty but didn't work when a socket is destroyed at the wrong moment
* (eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing
* with timers we just concede defeat and cli().
*/
- for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
- cli();
- sp = s_array[i];
- while(sp != NULL) {
- dest = sp->daddr;
- src = sp->saddr;
- destp = sp->dummy_th.dest;
- srcp = sp->dummy_th.source;
-
- /* Since we are Little Endian we need to swap the bytes :-( */
- destp = ntohs(destp);
- srcp = ntohs(srcp);
- timer_active = del_timer(&sp->timer);
- if (!timer_active)
- sp->timer.expires = 0;
- len+=sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
- i, src, srcp, dest, destp, sp->state,
- format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc,
- format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
- timer_active, sp->timer.expires, (unsigned) sp->retransmits,
- SOCK_INODE(sp->socket)->i_uid);
- if (timer_active)
- add_timer(&sp->timer);
- /*
- * All sockets with (port mod SOCK_ARRAY_SIZE) = i
- * are kept in sock_array[i], so we must follow the
- * 'next' link to get them all.
- */
- sp = sp->next;
- pos=begin+len;
- if(pos<offset)
+ for(i = 0; i < SOCK_ARRAY_SIZE; i++)
+ {
+ cli();
+ sp = s_array[i];
+ while(sp != NULL)
{
- len=0;
- begin=pos;
+ dest = sp->daddr;
+ src = sp->saddr;
+ destp = sp->dummy_th.dest;
+ srcp = sp->dummy_th.source;
+
+ /* Since we are Little Endian we need to swap the bytes :-( */
+ destp = ntohs(destp);
+ srcp = ntohs(srcp);
+ timer_active = del_timer(&sp->timer);
+ if (!timer_active)
+ sp->timer.expires = 0;
+ len+=sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
+ i, src, srcp, dest, destp, sp->state,
+ format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc,
+ format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
+ timer_active, sp->timer.expires, (unsigned) sp->retransmits,
+ sp->dead?0:SOCK_INODE(sp->socket)->i_uid);
+ if (timer_active)
+ add_timer(&sp->timer);
+ /*
+ * All sockets with (port mod SOCK_ARRAY_SIZE) = i
+ * are kept in sock_array[i], so we must follow the
+ * 'next' link to get them all.
+ */
+ sp = sp->next;
+ pos=begin+len;
+ if(pos<offset)
+ {
+ len=0;
+ begin=pos;
+ }
+ if(pos>offset+length)
+ break;
}
+ sti(); /* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
+ before this will clear before we jump back and cli, so its not as bad as it looks */
if(pos>offset+length)
break;
}
- sti(); /* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
- before this will clear before we jump back and cli, so its not as bad as it looks */
- if(pos>offset+length)
- break;
- }
- *start=buffer+(offset-begin);
- len-=(offset-begin);
- if(len>length)
- len=length;
- return len;
+ *start=buffer+(offset-begin);
+ len-=(offset-begin);
+ if(len>length)
+ len=length;
+ return len;
}
int tcp_get_info(char *buffer, char **start, off_t offset, int length)
{
- return get__netinfo(&tcp_prot, buffer,0, start, offset, length);
+ return get__netinfo(&tcp_prot, buffer,0, start, offset, length);
}
int udp_get_info(char *buffer, char **start, off_t offset, int length)
{
- return get__netinfo(&udp_prot, buffer,1, start, offset, length);
+ return get__netinfo(&udp_prot, buffer,1, start, offset, length);
}
int raw_get_info(char *buffer, char **start, off_t offset, int length)
{
- return get__netinfo(&raw_prot, buffer,1, start, offset, length);
+ return get__netinfo(&raw_prot, buffer,1, start, offset, length);
}
int snmp_get_info(char *buffer, char **start, off_t offset, int length)
{
- extern struct tcp_mib tcp_statistics;
- extern struct udp_mib udp_statistics;
- int len;
+ extern struct tcp_mib tcp_statistics;
+ extern struct udp_mib udp_statistics;
+ int len;
/*
extern unsigned long tcp_rx_miss, tcp_rx_hit1,tcp_rx_hit2;
*/
- len = sprintf (buffer,
- "Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates\n"
- "Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
- ip_statistics.IpForwarding, ip_statistics.IpDefaultTTL,
- ip_statistics.IpInReceives, ip_statistics.IpInHdrErrors,
- ip_statistics.IpInAddrErrors, ip_statistics.IpForwDatagrams,
- ip_statistics.IpInUnknownProtos, ip_statistics.IpInDiscards,
- ip_statistics.IpInDelivers, ip_statistics.IpOutRequests,
- ip_statistics.IpOutDiscards, ip_statistics.IpOutNoRoutes,
- ip_statistics.IpReasmTimeout, ip_statistics.IpReasmReqds,
- ip_statistics.IpReasmOKs, ip_statistics.IpReasmFails,
- ip_statistics.IpFragOKs, ip_statistics.IpFragFails,
- ip_statistics.IpFragCreates);
+ len = sprintf (buffer,
+ "Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates\n"
+ "Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+ ip_statistics.IpForwarding, ip_statistics.IpDefaultTTL,
+ ip_statistics.IpInReceives, ip_statistics.IpInHdrErrors,
+ ip_statistics.IpInAddrErrors, ip_statistics.IpForwDatagrams,
+ ip_statistics.IpInUnknownProtos, ip_statistics.IpInDiscards,
+ ip_statistics.IpInDelivers, ip_statistics.IpOutRequests,
+ ip_statistics.IpOutDiscards, ip_statistics.IpOutNoRoutes,
+ ip_statistics.IpReasmTimeout, ip_statistics.IpReasmReqds,
+ ip_statistics.IpReasmOKs, ip_statistics.IpReasmFails,
+ ip_statistics.IpFragOKs, ip_statistics.IpFragFails,
+ ip_statistics.IpFragCreates);
+
+ len += sprintf (buffer + len,
+ "Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps\n"
+ "Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+ icmp_statistics.IcmpInMsgs, icmp_statistics.IcmpInErrors,
+ icmp_statistics.IcmpInDestUnreachs, icmp_statistics.IcmpInTimeExcds,
+ icmp_statistics.IcmpInParmProbs, icmp_statistics.IcmpInSrcQuenchs,
+ icmp_statistics.IcmpInRedirects, icmp_statistics.IcmpInEchos,
+ icmp_statistics.IcmpInEchoReps, icmp_statistics.IcmpInTimestamps,
+ icmp_statistics.IcmpInTimestampReps, icmp_statistics.IcmpInAddrMasks,
+ icmp_statistics.IcmpInAddrMaskReps, icmp_statistics.IcmpOutMsgs,
+ icmp_statistics.IcmpOutErrors, icmp_statistics.IcmpOutDestUnreachs,
+ icmp_statistics.IcmpOutTimeExcds, icmp_statistics.IcmpOutParmProbs,
+ icmp_statistics.IcmpOutSrcQuenchs, icmp_statistics.IcmpOutRedirects,
+ icmp_statistics.IcmpOutEchos, icmp_statistics.IcmpOutEchoReps,
+ icmp_statistics.IcmpOutTimestamps, icmp_statistics.IcmpOutTimestampReps,
+ icmp_statistics.IcmpOutAddrMasks, icmp_statistics.IcmpOutAddrMaskReps);
- len += sprintf (buffer + len,
- "Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps\n"
- "Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
- icmp_statistics.IcmpInMsgs, icmp_statistics.IcmpInErrors,
- icmp_statistics.IcmpInDestUnreachs, icmp_statistics.IcmpInTimeExcds,
- icmp_statistics.IcmpInParmProbs, icmp_statistics.IcmpInSrcQuenchs,
- icmp_statistics.IcmpInRedirects, icmp_statistics.IcmpInEchos,
- icmp_statistics.IcmpInEchoReps, icmp_statistics.IcmpInTimestamps,
- icmp_statistics.IcmpInTimestampReps, icmp_statistics.IcmpInAddrMasks,
- icmp_statistics.IcmpInAddrMaskReps, icmp_statistics.IcmpOutMsgs,
- icmp_statistics.IcmpOutErrors, icmp_statistics.IcmpOutDestUnreachs,
- icmp_statistics.IcmpOutTimeExcds, icmp_statistics.IcmpOutParmProbs,
- icmp_statistics.IcmpOutSrcQuenchs, icmp_statistics.IcmpOutRedirects,
- icmp_statistics.IcmpOutEchos, icmp_statistics.IcmpOutEchoReps,
- icmp_statistics.IcmpOutTimestamps, icmp_statistics.IcmpOutTimestampReps,
- icmp_statistics.IcmpOutAddrMasks, icmp_statistics.IcmpOutAddrMaskReps);
-
- len += sprintf (buffer + len,
- "Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs\n"
- "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
- tcp_statistics.TcpRtoAlgorithm, tcp_statistics.TcpRtoMin,
- tcp_statistics.TcpRtoMax, tcp_statistics.TcpMaxConn,
- tcp_statistics.TcpActiveOpens, tcp_statistics.TcpPassiveOpens,
- tcp_statistics.TcpAttemptFails, tcp_statistics.TcpEstabResets,
- tcp_statistics.TcpCurrEstab, tcp_statistics.TcpInSegs,
- tcp_statistics.TcpOutSegs, tcp_statistics.TcpRetransSegs);
-
- len += sprintf (buffer + len,
- "Udp: InDatagrams NoPorts InErrors OutDatagrams\nUdp: %lu %lu %lu %lu\n",
- udp_statistics.UdpInDatagrams, udp_statistics.UdpNoPorts,
- udp_statistics.UdpInErrors, udp_statistics.UdpOutDatagrams);
-
-/*
+ len += sprintf (buffer + len,
+ "Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs\n"
+ "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+ tcp_statistics.TcpRtoAlgorithm, tcp_statistics.TcpRtoMin,
+ tcp_statistics.TcpRtoMax, tcp_statistics.TcpMaxConn,
+ tcp_statistics.TcpActiveOpens, tcp_statistics.TcpPassiveOpens,
+ tcp_statistics.TcpAttemptFails, tcp_statistics.TcpEstabResets,
+ tcp_statistics.TcpCurrEstab, tcp_statistics.TcpInSegs,
+ tcp_statistics.TcpOutSegs, tcp_statistics.TcpRetransSegs);
+
+ len += sprintf (buffer + len,
+ "Udp: InDatagrams NoPorts InErrors OutDatagrams\nUdp: %lu %lu %lu %lu\n",
+ udp_statistics.UdpInDatagrams, udp_statistics.UdpNoPorts,
+ udp_statistics.UdpInErrors, udp_statistics.UdpOutDatagrams);
+/*
len += sprintf( buffer + len,
"TCP fast path RX: H2: %ul H1: %ul L: %ul\n",
tcp_rx_hit2,tcp_rx_hit1,tcp_rx_miss);
*/
- if (offset >= len)
- {
- *start = buffer;
- return 0;
- }
- *start = buffer + offset;
- len -= offset;
- if (len > length)
- len = length;
- return len;
+ if (offset >= len)
+ {
+ *start = buffer;
+ return 0;
+ }
+ *start = buffer + offset;
+ len -= offset;
+ if (len > length)
+ len = length;
+ return len;
}
#include <asm/segment.h>
#include <linux/mm.h>
-#undef TCP_FASTPATH
+#define TCP_FASTPATH
#define SEQ_TICK 3
unsigned long seq_offset;
}
if(!sk->dead)
sk->data_ready(sk,0);
+ release_sock(sk);
return 0;
}
}