Commit 379932d2 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.28

parent 9d75228b
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 27
SUBLEVEL = 28
all: Version zImage
......
......@@ -254,39 +254,9 @@ static struct wait_queue *cdu31a_irq_wait = NULL;
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)
......
......@@ -235,7 +235,7 @@ static int lp_write_polled(struct inode * inode, struct file * file,
} 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;
......
......@@ -853,6 +853,7 @@ static int init_dev(dev_t device, struct tty_struct **ret_tty)
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.
......
......@@ -1184,7 +1184,7 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
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.
......@@ -1256,15 +1256,15 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
#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;
......@@ -1288,7 +1288,7 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
/* 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);
......@@ -1794,10 +1794,10 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
#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)) {
......@@ -1811,7 +1811,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
*/
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;
......@@ -1951,14 +1951,14 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
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;
......
......@@ -503,7 +503,7 @@ static int aha152x_porttest(int port_base)
return(i==16);
}
int aha152x_detect(int hostno)
int aha152x_detect(Scsi_Host_Template * tpnt)
{
int i, j, ok;
aha152x_config conf;
......@@ -653,10 +653,10 @@ int aha152x_detect(int hostno)
}
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 );
......
......@@ -10,7 +10,7 @@
#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 *));
......@@ -25,8 +25,10 @@ int aha152x_biosparam(Disk *, int, int*);
#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, \
......
......@@ -780,7 +780,7 @@ static int aha1542_query(int base_io, int * transl)
/* 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;
......@@ -794,7 +794,7 @@ int aha1542_detect(int hostnum)
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;
......@@ -900,7 +900,7 @@ int aha1542_detect(int hostnum)
count++;
continue;
unregister:
scsi_unregister(shpnt, sizeof(struct aha1542_hostdata));
scsi_unregister(shpnt);
continue;
};
......
......@@ -128,7 +128,7 @@ struct ccb { /* Command Control Block 5.3 */
/* 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 *);
......@@ -144,14 +144,23 @@ int aha1542_biosparam(Disk *, int, int*);
#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
......@@ -425,7 +425,7 @@ void aha1740_getconfig(void)
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"));
......
......@@ -152,7 +152,7 @@ struct ecb { /* Enhanced Control Block 6.1 */
#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 *);
......@@ -167,14 +167,24 @@ int aha1740_biosparam(Disk *, int, int*);
#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
......@@ -912,7 +912,7 @@ static int buslogic_query(unsigned int base, int *trans)
}
/* return non-zero on detection */
int buslogic_detect(int hostnum)
int buslogic_detect(Scsi_Host_Template * tpnt)
{
unsigned char dma;
unsigned char irq;
......@@ -932,7 +932,7 @@ int buslogic_detect(int hostnum)
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];
......@@ -1085,7 +1085,7 @@ int buslogic_detect(int hostnum)
count++;
continue;
unregister:
scsi_unregister(SHpnt, sizeof (struct hostdata));
scsi_unregister(SHpnt);
}
return count;
}
......
......@@ -12,7 +12,7 @@
#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);
......@@ -21,8 +21,10 @@ int buslogic_biosparam(Disk *, int, int *);
#define BUSLOGIC_CMDLUN 1 /* ??? */
#define BUSLOGIC { "BusLogic", \
#define BUSLOGIC { NULL, \
"BusLogic", \
buslogic_detect, \
NULL, \
buslogic_info, \
0, /* no command func */ \
buslogic_queuecommand, \
......
......@@ -258,7 +258,6 @@ static void *bios_base = NULL;
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;
......@@ -480,7 +479,7 @@ static int fdomain_test_loopback( void )
return 0;
}
int fdomain_16x0_detect( int hostnum )
int fdomain_16x0_detect(Scsi_Host_Template * tpnt)
{
int i, j;
int flag = 0;
......@@ -614,11 +613,7 @@ int fdomain_16x0_detect( int hostnum )
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" );
......@@ -659,7 +654,7 @@ int fdomain_16x0_detect( int hostnum )
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
......@@ -679,7 +674,7 @@ int fdomain_16x0_detect( int hostnum )
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);
......
......@@ -25,7 +25,7 @@
#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 );
......@@ -34,8 +34,10 @@ int fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
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, \
......@@ -43,5 +45,11 @@ int fdomain_16x0_biosparam(Disk *, int, int * );
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
......@@ -111,18 +111,18 @@ static struct sigaction sa = { generic_NCR5380_intr, 0,
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;
......@@ -131,7 +131,7 @@ int generic_NCR5380_detect(int hostno) {
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);
......@@ -144,13 +144,13 @@ int generic_NCR5380_detect(int hostno) {
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);
......
......@@ -34,7 +34,7 @@
#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 *);
......@@ -54,8 +54,8 @@ 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, \
......
......@@ -108,7 +108,9 @@ static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hos
* 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,
......@@ -152,7 +154,7 @@ Scsi_Host_Template scsi_hosts[] =
#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.
......@@ -160,44 +162,44 @@ Scsi_Host_Template scsi_hosts[] =
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);
......@@ -205,9 +207,9 @@ struct Scsi_Host * scsi_register(int i, int 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;
......@@ -221,19 +223,17 @@ struct Scsi_Host * scsi_register(int i, int j){
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
......@@ -241,36 +241,38 @@ scsi_init(unsigned long memory_start,unsigned long memory_end)
*/
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){
};
......@@ -283,8 +285,8 @@ int MAX_SD=0;
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){
};
......@@ -297,8 +299,8 @@ int MAX_SR=0;
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){
};
......@@ -310,8 +312,8 @@ int MAX_ST=0;
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){
};
......
......@@ -46,8 +46,12 @@
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.
......@@ -71,8 +75,10 @@ typedef struct
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.
......@@ -218,6 +224,7 @@ typedef struct
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;
......@@ -238,21 +245,36 @@ struct Scsi_Host
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
......@@ -278,19 +278,19 @@ void pas16_setup(char *str, int *ints) {
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;
......@@ -309,27 +309,27 @@ int pas16_detect(int hostno) {
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);
......@@ -342,17 +342,17 @@ int pas16_detect(int hostno) {
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)
......@@ -368,7 +368,6 @@ int pas16_detect(int hostno) {
++current_override;
++count;
++hostno;
}
return count;
}
......
......@@ -116,7 +116,7 @@
#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 *);
......@@ -141,7 +141,8 @@ 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, \
......
......@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/malloc.h>
#include <asm/irq.h>
#include "../block/blk.h"
......@@ -74,8 +75,8 @@ Scsi_Device * scsi_devices = NULL;
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
......@@ -214,217 +215,209 @@ void scsi_luns_setup(char *str, int *ints) {
* 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
......@@ -434,8 +427,8 @@ static void scan_scsis (void)
* 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
......@@ -443,64 +436,69 @@ static void scan_scsis (void)
*/
#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 */
......@@ -560,34 +558,34 @@ something else to finish. This routine assumes that interrupts are
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
......@@ -636,7 +634,8 @@ guarantee that the host remain not busy. Keep in mind the
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;
......@@ -646,21 +645,21 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
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;
};
......@@ -677,16 +676,16 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
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
......@@ -987,7 +986,7 @@ static int check_sense (Scsi_Cmnd * SCpnt)
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;
......@@ -1698,6 +1697,38 @@ int scsi_free(void *obj, unsigned int len)
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
......@@ -1706,90 +1737,90 @@ int scsi_free(void *obj, unsigned int len)
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++;
......@@ -1814,6 +1845,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
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;
}
......@@ -1866,11 +1898,11 @@ static void
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",
......@@ -1893,7 +1925,6 @@ scsi_dump_status(void)
(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 */
......@@ -1919,3 +1950,5 @@ scsi_dump_status(void)
}
}
#endif
......@@ -258,7 +258,8 @@ extern const unsigned char scsi_command_size[8];
*/
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;
......@@ -406,7 +407,7 @@ typedef struct scsi_pointer {
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 */
......@@ -493,27 +494,27 @@ extern void scsi_do_cmd (Scsi_Cmnd *, const void *cmnd ,
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)
......@@ -560,7 +561,7 @@ static void end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
need_resched = 1;
}
req->dev = -1;
wake_up(&scsi_devices[SCpnt->index].device_wait);
wake_up(&SCpnt->device->device_wait);
return;
}
......@@ -584,17 +585,20 @@ static void end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
#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
......@@ -100,7 +100,6 @@ static int npart = 0;
#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,};
......@@ -513,9 +512,8 @@ static void scsi_debug_intr_handle(void)
}
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;
......@@ -528,7 +526,7 @@ int scsi_debug_abort(Scsi_Cmnd * SCpnt)
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];
......
......@@ -2,10 +2,10 @@
#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 *);
......@@ -16,7 +16,7 @@ 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, \
......
......@@ -91,7 +91,7 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
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);
......@@ -135,7 +135,7 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
result = SCpnt->result;
SCpnt->request.dev = -1;
wake_up(&scsi_devices[SCpnt->index].device_wait);
wake_up(&SCpnt->device->device_wait);
return result;
}
......@@ -175,7 +175,7 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
#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);
......@@ -204,10 +204,10 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
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
{
......@@ -236,8 +236,8 @@ int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
{
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:
......
......@@ -42,7 +42,7 @@ static const char RCSid[] = "$Header:";
#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;
......@@ -347,7 +347,7 @@ static void do_sd_request (void)
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();
......@@ -365,7 +365,7 @@ static void do_sd_request (void)
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;
......@@ -734,7 +734,7 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
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);
}
......@@ -801,7 +801,7 @@ static int sd_init_onedisk(int i)
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;
......@@ -852,7 +852,7 @@ static int sd_init_onedisk(int i)
};
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);
......@@ -896,7 +896,7 @@ static int sd_init_onedisk(int i)
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*/
......@@ -1031,10 +1031,8 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
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){
......
......@@ -272,8 +272,9 @@ static inline void borken_wait(void) {
#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
......@@ -336,7 +337,7 @@ static struct sigaction seagate_sigaction = {
#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)
{
......@@ -349,7 +350,8 @@ static struct sigaction seagate_sigaction = {
* 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);
......@@ -615,7 +617,7 @@ static int internal_command(unsigned char target, unsigned char lun, const void
st0x_aborted = 0;
#ifdef SLOW_HANDSHAKE
borken = (int) scsi_devices[SCint->index].borken;
borken = (int) SCint->device->borken;
#endif
#if (DEBUG & PRINT_COMMAND)
......
......@@ -12,7 +12,7 @@
$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 *));
......@@ -26,7 +26,8 @@ int seagate_st0x_reset(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, \
......
......@@ -252,7 +252,7 @@ static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
#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);
......@@ -317,11 +317,10 @@ unsigned long sg_init(unsigned long mem_start, unsigned long mem_end)
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)
......
......@@ -307,7 +307,7 @@ static void do_sr_request (void)
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();
......@@ -325,7 +325,7 @@ static void do_sr_request (void)
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;
......@@ -623,10 +623,8 @@ are any multiple of 512 bytes long. */
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){
......@@ -657,7 +655,7 @@ static void get_sectorsize(int i){
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 {
......@@ -689,7 +687,7 @@ static void get_sectorsize(int i){
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;
......
......@@ -43,7 +43,7 @@ static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned
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);
......@@ -85,7 +85,7 @@ static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned
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;
}
......
......@@ -230,7 +230,7 @@ back_over_eof(int dev)
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,
......@@ -275,7 +275,7 @@ flush_write_buffer(int dev)
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) /
......@@ -411,7 +411,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
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);
......@@ -597,7 +597,7 @@ scsi_tape_close(struct inode * inode, struct file * filp)
#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);
......@@ -718,7 +718,7 @@ st_write(struct inode * inode, struct file * filp, char * buf, int count)
if (!STp->do_async_writes)
write_threshold--;
SCpnt = allocate_device(NULL, (STp->device)->index, 1);
SCpnt = allocate_device(NULL, STp->device, 1);
total = count;
......@@ -925,7 +925,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int 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; ) {
......@@ -1413,7 +1413,7 @@ st_int_ioctl(struct inode * inode,struct file * file,
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,
......@@ -1594,7 +1594,7 @@ st_ioctl(struct inode * inode,struct file * file,
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);
......@@ -1682,17 +1682,16 @@ void st_attach(Scsi_Device * SDp){
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);
......@@ -1705,7 +1704,7 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
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;
......@@ -1726,17 +1725,18 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
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 */
......
......@@ -181,19 +181,19 @@ void t128_setup(char *str, int *ints) {
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;
......@@ -207,7 +207,7 @@ int t128_detect(int hostno) {
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
......@@ -215,20 +215,20 @@ int t128_detect(int hostno) {
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);
......@@ -241,17 +241,17 @@ int t128_detect(int hostno) {
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)
......@@ -267,7 +267,6 @@ int t128_detect(int hostno) {
++current_override;
++count;
++hostno;
}
return count;
}
......
......@@ -93,7 +93,7 @@
#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 *);
......@@ -118,7 +118,8 @@ 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, \
......
......@@ -241,9 +241,6 @@ static struct ultrastor_config
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.) */
......@@ -339,7 +336,7 @@ static void log_ultrastor_abort(register struct ultrastor_config *config,
}
#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;
......@@ -486,9 +483,8 @@ static int ultrastor_14f_detect(int hostnum)
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;
......@@ -505,14 +501,14 @@ static int ultrastor_14f_detect(int hostnum)
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;
......@@ -589,12 +585,11 @@ static int ultrastor_24f_detect(int hostnum)
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;
......@@ -611,15 +606,15 @@ static int ultrastor_24f_detect(int hostnum)
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)
......@@ -699,7 +694,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
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;
......
......@@ -13,7 +13,7 @@
#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 *);
......@@ -29,12 +29,24 @@ int ultrastor_biosparam(Disk *, int, int *);
#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
......
......@@ -156,7 +156,6 @@ typedef volatile struct mailbox{
*
*/
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 */
......@@ -1090,7 +1089,7 @@ void wd7000_revision(Adapter *host)
}
int wd7000_detect(int hostnum)
int wd7000_detect(Scsi_Host_Template * tpnt)
/*
* Returns the number of adapters this driver is supporting.
*
......@@ -1137,21 +1136,21 @@ int wd7000_detect(int hostnum)
* 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;
}
......
......@@ -12,7 +12,7 @@
#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 *);
......@@ -38,9 +38,10 @@ int wd7000_biosparam(Disk *, int, int*);
#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, \
......
......@@ -6,7 +6,6 @@
* (C) 1991 Linus Torvalds - minix filesystem
*/
#include <linux/config.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/iso_fs.h>
......@@ -21,16 +20,6 @@
#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;
......
......@@ -22,7 +22,7 @@
#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
/*
......
......@@ -20,6 +20,7 @@
* 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
......@@ -55,90 +56,91 @@
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);
}
......@@ -148,74 +150,73 @@ int raw_get_info(char *buffer, char **start, off_t offset, int 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;
}
......@@ -155,7 +155,7 @@
#include <asm/segment.h>
#include <linux/mm.h>
#undef TCP_FASTPATH
#define TCP_FASTPATH
#define SEQ_TICK 3
unsigned long seq_offset;
......@@ -3844,6 +3844,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
}
if(!sk->dead)
sk->data_ready(sk,0);
release_sock(sk);
return 0;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment