E: almesber@bernina.ethz.ch
D: dosfs, LILO, some fd features, various other hacks here and there
+N: H. Peter Anvin
+E: Peter.Anvin@linux.org
+D: Author of the SYSLINUX boot loader, maintainer of the linux.* news
+D: hierarchy, responsible for various console and other hacks
+S: 4390 Albany Dr. #46
+S: San Jose CA 95129
+S: USA
+
N: Derek Atkins
E: warlord@MIT.EDU
D: Linux-AFS Port, random kernel hacker,
VERSION = 1
PATCHLEVEL = 3
-SUBLEVEL = 12
+SUBLEVEL = 13
ARCH = i386
struct file * file = NULL;
if (flags & (MAP_HASSEMAPHORE | MAP_INHERIT | MAP_UNALIGNED))
- printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, osf_flags);
+ printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, flags);
if (!(flags & MAP_ANONYMOUS)) {
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
/*
* Handle user-level unaligned fault. For now, simply send a
- * SIGSEGV---there should be little reason for users not wanting to
+ * SIGBUS---there should be little reason for users not wanting to
* fix their code instead. Notice that we have the regular kernel
* stack layout here, so finding the appropriate registers is a little
* more difficult than in the kernel case. Also, we'd need to do
struct pt_regs regs)
{
regs.pc -= 4; /* make pc point to faulting insn */
- send_sig(SIGSEGV, current, 1);
+ send_sig(SIGBUS, current, 1);
}
/*
* Changed to prevent keyboard lockups on AST Power Exec.
* 28Jul93 Brad Bosch - brad@lachman.com
*
- * Modified by Johan Myreen (jem@cs.hut.fi) 04Aug93
+ * Modified by Johan Myreen (jempandora.pp.fi) 04Aug93
* to include support for QuickPort mouse.
*
* Changed references to "QuickPort" with "82C710" since "QuickPort"
* is not what this driver is all about -- QuickPort is just a
* connector type, and this driver is for the mouse port on the Chips
- * & Technologies 82C710 interface chip. 15Nov93 jem@cs.hut.fi
+ * & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi
*/
/* Uncomment the following line if your mouse needs initialization. */
static int aux_busy = 0;
static int aux_present = 0;
static int poll_aux_status(void);
+static int poll_aux_status_nosleep(void);
#ifdef CONFIG_82C710_MOUSE
static int qp_present = 0;
static void aux_write_dev(int val)
{
- poll_aux_status();
+ poll_aux_status_nosleep();
outb_p(AUX_MAGIC_WRITE,AUX_COMMAND); /* write magic cookie */
- poll_aux_status();
+ poll_aux_status_nosleep();
outb_p(val,AUX_OUTPUT_PORT); /* write data */
}
int retries = 0;
aux_write_dev(val); /* write the value to the device */
- while ((inb(AUX_STATUS) & AUX_OBUF_FULL) != AUX_OBUF_FULL
- && retries < MAX_RETRIES) { /* wait for ack */
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + (5*HZ + 99) / 100;
- schedule();
- retries++;
- }
+ poll_aux_status_nosleep();
if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
{
psaux_fops.write = write_qp;
psaux_fops.open = open_qp;
psaux_fops.release = release_qp;
- poll_qp_status();
} else
#endif
if (aux_device_present == 0xaa) {
printk("PS/2 auxiliary pointing device detected -- driver installed.\n");
aux_present = 1;
kbd_read_mask = AUX_OBUF_FULL;
- poll_aux_status();
} else {
return kmem_start; /* No mouse at all */
}
aux_write_ack(AUX_SET_RES);
aux_write_ack(3); /* 8 counts per mm */
aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
- poll_aux_status();
+ poll_aux_status_nosleep();
#endif /* INITIALIZE_DEVICE */
outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */
- poll_aux_status();
}
return kmem_start;
}
return !(retries==MAX_RETRIES);
}
+static int poll_aux_status_nosleep(void)
+{
+ int retries = 0;
+
+ while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
+ if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+ inb_p(AUX_INPUT_PORT);
+ retries++;
+ }
+ return !(retries == 1000000);
+}
+
#ifdef CONFIG_82C710_MOUSE
/*
* Wait for device to send output char and flush any input char.
} else goto wait;
}
+ i = verify_area (VERIFY_WRITE,buf,nr);
+ if (i != 0) {
+ ppp->us_rbuff_lock = 0;
+ return i;
+ }
+
/* reset the time of the last read operation */
ppp->ddinfo.nip_rjiffies = jiffies;
current->timeout = 0;
PRINTKN (3,(KERN_DEBUG "ppp_read: sleeping\n"));
interruptible_sleep_on (&ppp->read_wait);
+
+ /* Ensure that the ppp device is still attached. */
+ ppp = ppp_find(tty);
+ if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse)
+ return 0;
+
if (current->signal & ~current->blocked)
return -EINTR;
} while (1);
nr = ppp->mtu;
}
+ i = verify_area (VERIFY_READ,buf,nr);
+ if (i != 0)
+ return i;
+
if (ppp_debug >= 3)
ppp_print_buffer ("write frame", buf, nr, USER_DS);
current->timeout = 0;
PRINTKN (3,(KERN_DEBUG "ppp_write: sleeping\n"));
interruptible_sleep_on(&ppp->write_wait);
+
+ /* Ensure that the ppp device is still attached. */
+ ppp = ppp_find(tty);
+ if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse)
+ return 0;
+
if (current->signal & ~current->blocked)
return -EINTR;
}
+Wed Jul 19 10:43:15 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
+ attached devices.
+
+ * scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
+ eata_dma_proc.c to produce some device info for /proc/scsi.
+
+ * eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
+ Changed handling of internal SCSI commands send to the HBA.
+
+
+Wed Jul 19 10:09:17 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * Linux 1.3.11 released.
+
+ * eata_dma.c (eata_queue)(eata_int_handler): Added code to do
+ command latency measurements if requested by root through
+ /proc/scsi interface.
+ Throughout Use HZ constant for time references.
+
+ * eata_pio.c: Use HZ constant for time references.
+
+ * aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
+ to GNU style.
+
+ * scsi.h: Added READ_12 command opcode constant
+
+Wed Jul 19 09:25:30 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * Linux 1.3.10 released.
+
+ * scsi_proc.c (dispatch_scsi_info): Removed unused variable.
+
+Wed Jul 19 09:25:30 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * Linux 1.3.9 released.
+
+ * scsi.c Blacklist concept expanded to 'support' more device
+ deficiencies. blacklist[] renamed to device_list[]
+ (scan_scsis): Code cleanup.
+
+ * scsi_debug.c (scsi_debug_proc_info): Added support to control
+ device lockup simulation via /proc/scsi interface.
+
+
+Wed Jul 19 09:22:34 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * Linux 1.3.7 released.
+
+ * scsi_proc.c: Fixed a number of bugs in directory handling
+
+Wed Jul 19 09:18:28 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * Linux 1.3.5 released.
+
+ * Native wide, multichannel and /proc/scsi support now in official
+ kernel distibution.
+
+ * scsi.c/h, hosts.c/h et al reindended to increase readability
+ (especially on 80 column wide terminals).
+
+ * scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
+ /proc/scsi/scsi which allows root to scan for hotplugged devices.
+
+ * scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
+ (scan_scsis): Added some 'spagetti' code to allow scanning for
+ single devices.
+
+
+Thu Jun 20 15:20:27 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * proc.c: Renamed to scsi_proc.c
+
+Mon Jun 12 20:32:45 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+ * Linux 1.3.0 released.
+
Mon May 15 19:33:14 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
* scsi.c: Added native multichannel and wide scsi support.
* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries):
Thu May 4 17:58:48 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
- * sd.c (requeue_sd_request): zero out the scatterlist only if
+ * sd.c (requeue_sd_request): Zero out the scatterlist only if
scsi_malloc returned memory for it.
- * eata_dma.c (register_HBA) (eata_queue): add support for
+ * eata_dma.c (register_HBA) (eata_queue): Add support for
large scatter/gatter tables and set use_clustering accordingly
- * hosts.c: make use_clustering changable in the Scsi_Host structure.
+ * hosts.c: Make use_clustering changable in the Scsi_Host structure.
Wed Apr 12 15:25:52 1995 Eric Youngdale (eric@andante)
* Thanks also to Greg Hosler who did a lot of testing and *
* found quite a number of bugs during the development. *
************************************************************
- * last change: 95/07/11 OS: Linux 1.3.9 *
+ * last change: 95/07/18 OS: Linux 1.3.10 *
************************************************************/
/* Look in eata_dma.h for configuration and revision information */
static struct eata_sp *status = 0; /* Statuspacket array */
static void *dma_scratch = 0;
-static uint internal_command_finished = TRUE;
-static unchar HBA_interpret = FALSE;
static u32 fake_int_base;
-static u32 fake_int_result;
+static int fake_int_result;
+static int fake_int_happened;
static ulong int_counter = 0;
static ulong queue_counter = 0;
-void eata_scsi_done (Scsi_Cmnd * SCpnt)
+void eata_scsi_done (Scsi_Cmnd * scmd)
{
+ scmd->request.dev = 0xfffe;
+
+ if (scmd->request.sem != NULL)
+ up(scmd->request.sem);
+
return;
}
void eata_fake_int_handler(s32 irq, struct pt_regs * regs)
{
fake_int_result = inb(fake_int_base + HA_RSTATUS);
+ fake_int_happened = TRUE;
DBG(DBG_INTR3, printk("eata_fake_int_handler called irq%d base %#x"
" res %#x\n", irq, fake_int_base, fake_int_result));
return;
}
#endif
-const char *eata_info(struct Scsi_Host *host)
-{
- static char *information = "EATA SCSI HBA Driver";
- return information;
-}
void eata_int_handler(int irq, struct pt_regs * regs)
{
sp=&SD(sh)->sp;
- cp = sp->ccb;
+ cp = sp->ccb; /* Has been passed thru, no conversion needed */
cmd = cp->cmd;
base = (uint) cmd->host->base;
#endif
cp->status = FREE; /* now we can release the slot */
-
- restore_flags(flags);
- if(cmd->scsi_done != eata_scsi_done) cmd->scsi_done(cmd);
- else {
- internal_command_finished = TRUE;
- HBA_interpret = FALSE;
- }
- save_flags(flags);
- cli();
+ cmd->scsi_done(cmd);
}
restore_flags(flags);
while (inb(base + HA_RAUXSTAT) & HA_ABUSY)
if (--loop == 0)
return(FALSE);
-
+
+ /* And now the address in nice little byte chunks */
outb( addr & 0x000000ff, base + HA_WDMAADDR);
outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
return(TRUE);
}
-#if 0
+#if 0
inline int eata_send_immediate(u32 addr, u32 base, u8 cmnd, u8 cmnd2, u8 id,
u8 lun)
{
cli();
queue_counter++;
-
- if (done == (void *)eata_scsi_done) {
- if (internal_command_finished == TRUE)
- internal_command_finished = FALSE;
- else
- cmd->result = (DID_ERROR << 16) + QUEUE_FULL;
- }
-
+
hd = HD(cmd);
sh = cmd->host;
default:
cp->DataIn = TRUE; /* Input mode */
}
-
- if ((done == (void *) eata_scsi_done && HBA_interpret == TRUE)
- || cmd->target == sh->this_id)
+
+ /* FIXME: This will will have to be changed once the midlevel driver
+ * allows different HBA IDs on every channel.
+ */
+ if (cmd->target == sh->this_id)
cp->Interpret = TRUE; /* Interpret command */
-
+
if (cmd->use_sg) {
cp->scatter = TRUE; /* SG mode */
if (cp->sg_list == NULL) {
cp->sg_list = kmalloc(SG_SIZE_BIG*sizeof(struct eata_sg_list),
GFP_ATOMIC | GFP_DMA);
}
- cp->cp_dataDMA = htonl((ulong)cp->sg_list);
- if (cp->cp_dataDMA == 0)
+ if (cp->sg_list == NULL)
panic("eata_dma: Run out of DMA memory for SG lists !\n");
+ cp->cp_dataDMA = htonl(virt_to_bus(cp->sg_list));
cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list));
sl=(struct scatterlist *)cmd->request_buffer;
for(i = 0; i < cmd->use_sg; i++, sl++){
- cp->sg_list[i].data = htonl((u32) sl->address);
+ cp->sg_list[i].data = htonl(virt_to_bus(sl->address));
cp->sg_list[i].len = htonl((u32) sl->length);
}
} else {
cp->scatter = FALSE;
cp->cp_datalen = htonl(cmd->request_bufflen);
- cp->cp_dataDMA = htonl((u32)cmd->request_buffer);
+ cp->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer));
}
cp->Auto_Req_Sen = TRUE;
- cp->cp_reqDMA = htonl((u32) cmd->sense_buffer);
+ cp->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
cp->reqlen = sizeof(cmd->sense_buffer);
cp->cp_id = cmd->target;
cp->cp_identify = TRUE;
memcpy(cp->cp_cdb, cmd->cmnd, cmd->cmd_len);
- cp->cp_statDMA = htonl((u32) &(hd->sp));
+ cp->cp_statDMA = htonl(virt_to_bus(&(hd->sp)));
- cp->cp_viraddr = cp;
+ cp->cp_viraddr = cp; /* This will be passed thru, so we don't need to convert it */
cp->cmd = cmd;
cmd->host_scribble = (char *)&hd->ccb[y];
cmd->result = DID_ERROR << 16;
printk("eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR,"
" done.\n", cmd->target, cmd->pid);
+
restore_flags(flags);
- if(done != (void *)eata_scsi_done) done(cmd);
- return (0);
+ done(cmd);
+ return(0);
}
DBG(DBG_QUEUE,printk("Queued base %#.4x pid: %ld target: %x lun: %x "
"slot %d irq %d\n", (s32)sh->base, cmd->pid,
cmd->target, cmd->lun, y, sh->irq));
DBG(DBG_QUEUE && DBG_DELAY, DEL2(200));
restore_flags(flags);
- return (0);
+ return(0);
}
restore_flags(flags);
time = jiffies;
- while (jiffies < (time + (3 * HZ)) && limit++ < 10000000)
- /* nothing */;
+ while (jiffies < (time + (3 * HZ)) || limit++ < 10000000)
+ /* As time goes by... */;
save_flags(flags);
cli();
cp->DataIn = TRUE;
cp->Interpret = TRUE; /* Interpret command */
+ cp->cp_dispri = TRUE;
+ cp->cp_identify = TRUE;
- cp->cp_datalen = htonl(255);
- cp->cp_dataDMA = htonl((s32)buff);
+ cp->cp_datalen = htonl(56);
+ cp->cp_dataDMA = htonl(virt_to_bus(buff));
+ cp->cp_statDMA = htonl(virt_to_bus(sp));
cp->cp_viraddr = cp;
cp->cp_id = id;
cp->cp_cdb[1] = 0;
cp->cp_cdb[2] = 0;
cp->cp_cdb[3] = 0;
- cp->cp_cdb[4] = 255;
+ cp->cp_cdb[4] = 56;
cp->cp_cdb[5] = 0;
- cp->cp_statDMA = htonl((ulong) sp);
-
fake_int_base = base;
- fake_int_result = 0;
+ fake_int_result = FALSE;
+ fake_int_happened = FALSE;
eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);
- i = jiffies + (3 * HZ) ;
- while (fake_int_result == FALSE && jiffies <= i)
+ i = jiffies + (3 * HZ);
+ while (fake_int_happened == FALSE && jiffies <= i)
barrier();
DBG(DBG_INTR3, printk("fake_int_result: %#x hbastat %#x scsistat %#x,"
" buff %p sp %p\n",
- fake_int_result, (u32) (sp->hba_stat & 0x7f),
+ fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/),
(u32) sp->scsi_stat, buff, sp));
scsi_init_free((void *)cp, sizeof(struct eata_ccb));
inb((u32) (base) + HA_RSTATUS);
eata_send_command(0, base, EATA_CMD_RESET);
i = jiffies;
- while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
+ while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
barrier();
return (NULL);
} else
}
}
- if (bustype != IS_EISA)
+#if !(NEWSTUFF)
+ if (bustype != IS_EISA && bustype != IS_ISA)
+#endif
buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]);
if (buff == NULL) {
- if (bustype == IS_EISA) {
+#if !(NEWSTUFF)
+ if (bustype == IS_EISA || bustype == IS_ISA) {
bugs = bugs || BROKEN_INQUIRY;
} else {
+#endif
if (gc->DMA_support == FALSE)
printk("HBA at %#.4x doesn't support DMA. Sorry\n", base);
else
if (gc->IRQ_TR == FALSE)
reg_IRQL[gc->IRQ] = FALSE;
return (FALSE);
+#if !(NEWSTUFF)
}
+#endif
}
if (gc->DMA_support == FALSE && buff != NULL)
if(ntohs(gc->queuesiz) == 0) {
gc->queuesiz = ntohs(64);
printk("Warning: Queue size has to be corrected. Assuming 64 queueslots\n"
- " This might be a PM2012B with a defective Firmware\n");
+ " This might be a PM2012B with a defective Firmware\n");
}
size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long))
hd->bustype = bustype;
if(ntohl(gc->len) >= 0x22) {
- sh->max_id = gc->MAX_ID;
- sh->max_lun = gc->MAX_LUN;
+ sh->max_id = gc->MAX_ID + 1;
+ sh->max_lun = gc->MAX_LUN + 1;
} else {
sh->max_id = 8;
sh->max_lun = 8;
* SCSI midlevel code should support different HBA ids on every channel
*/
sh->this_id = gc->scsi_id[3];
- sh->can_queue = ntohs(gc->queuesiz) - 1; /* Keep one free for internals */
+ sh->can_queue = ntohs(gc->queuesiz);
- if (gc->OCS_enabled == TRUE)
+ if (gc->OCS_enabled == TRUE) {
if(hd->bustype != IS_ISA)
sh->cmd_per_lun = sh->can_queue/C_P_L_DIV;
else
- sh->cmd_per_lun = 8;
- else
+ sh->cmd_per_lun = 8; /* We artificially limit this to conserve memory,
+ * which would be needed for ISA bounce buffers */
+ } else
sh->cmd_per_lun = 1;
/* FIXME:
(u16 *) & com_adr))) {
if (!((com_adr & PCI_COMMAND_IO) &&
(com_adr & PCI_COMMAND_MASTER))) {
- printk("HBA has IO or BUSMASTER mode disabled\n");
+ printk("eata_dma: HBA has IO or BUSMASTER mode disabled\n");
continue;
}
} else
printk("eata_dma: error %x while reading "
"PCI_COMMAND\n", error);
} else
- printk("DEVICECLASSID %x didn't match\n", rev_device);
+ printk("eata_dma: DEVICECLASSID %x didn't match\n",
+ rev_device);
} else {
printk("eata_dma: error %x while reading PCI_CLASS_BASE\n",
error);
break;
}
}
- } else if ((base & 0x0fff) == 0x0c88) {
- x = (base >> 12) & 0x0f;
- EISAbases[x] = 0;
- }
+ } else if ((base & 0x0fff) == 0x0c88)
+ EISAbases[(base >> 12) & 0x0f] = 0;
continue; /* break; */
} else if (check_blink_state(base) == TRUE) {
printk("eata_dma: HBA is in BLINK state.\n"
}
}
}
- } else
+ } else {
printk("eata_dma: error %x while reading "
"PCI_BASE_ADDRESS_0\n", error);
+ }
}
- } else
+ } else {
printk("eata_dma: No BIOS32 extensions present. This driver release "
"still depends on it.\n"
" Skipping scan for PCI HBAs. \n");
+ }
#endif /* #ifndef CONFIG_PCI */
return;
}
status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
dma_scratch = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
+ if(status == NULL || dma_scratch == NULL) {
+ printk("eata_dma: can't allocate enough memory to probe for hosts !\n");
+ return(0);
+ }
+
find_PCI(&gc, tpnt);
find_EISA(&gc, tpnt);
find_ISA(&gc, tpnt);
- for (i = 0; i <= MAXIRQ; i++)
- if (reg_IRQ[i]){
- free_irq(i);
+ for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */
+ if (reg_IRQ[i]){ /* exchange the interrupt handler which */
+ free_irq(i); /* we used for probing with the real one */
request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma");
}
-
+ }
HBA_ptr = first_HBA;
if (registered_HBAs != 0) {
printk("\nHBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: "
"ID: Pr: QS: SG: CPL:\n");
for (i = 1; i <= registered_HBAs; i++) {
- printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d",
+ printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d",
HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')?
"PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
printk(" %2x ", HBA_ptr->dma_channel);
else
printk(" %s", "BMST");
- printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel,
+ printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel,
HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N',
HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
HBA_ptr = SD(HBA_ptr)->next;
* Header file for eata_dma.c Linux EATA-DMA SCSI driver *
* (c) 1993,94,95 Michael Neuffer *
*********************************************************
-* last change: 95/06/20 *
+* last change: 95/07/18 *
********************************************************/
#define VER_MAJOR 2
#define VER_MINOR 5
-#define VER_SUB "7a"
+#define VER_SUB "7b"
/************************************************************************
************************************************************************/
#define CHECKPAL 0 /* EISA pal checking on/off */
+#define NEWSTUFF 1 /* Some changes for ISA/EISA boards */
/************************************************************************
* Debug options. *
#define EATA_DMA { \
NULL, NULL, \
- eata_proc_info,/* procinfo */ \
- "eata_dma", /* proc dir entry */ \
- PROC_SCSI_EATA,/* proc dir inode */ \
- "EATA (Extended Attachment) driver", \
+ eata_proc_info,/* procinfo */ \
+ "eata_dma", /* proc dir entry */ \
+ PROC_SCSI_EATA,/* proc dir inode */ \
+ "EATA (Extended Attachment) HBA driver", \
eata_detect, \
eata_release, \
NULL, NULL, \
-
-#define MAX_SCSI_DEVICE_CODE 10
-const char *const scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
-{
- "Direct-Access ",
- "Sequential-Access",
- "Printer ",
- "Processor ",
- "WORM ",
- "CD-ROM ",
- "Scanner ",
- "Optical Device ",
- "Medium Changer ",
- "Communications "
-};
+extern void proc_print_scsidevice(Scsi_Device *scd, char *buffer,
+ int *size, int len);
void swap_statistics(u8 *p)
*/
int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
{
+ int orig_length = length;
+
if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) {
- buffer += 9;
- length -= 9;
- if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
- SD(HBA_ptr)->do_latency = TRUE;
- return(length+9);
- }
-
- if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
- SD(HBA_ptr)->do_latency = FALSE;
- return(length+9);
- }
-
- printk("Unknown command:%s length: %d\n", buffer, length);
+ buffer += 9;
+ length -= 9;
+ if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
+ SD(HBA_ptr)->do_latency = TRUE;
+ return(orig_length);
+ }
+
+ if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
+ SD(HBA_ptr)->do_latency = FALSE;
+ return(orig_length);
+ }
+
+ printk("Unknown command:%s length: %d\n", buffer, length);
} else
- printk("Wrong Signature:%10s\n", (char *) ((ulong)buffer-9));
+ printk("Wrong Signature:%10s\n", buffer);
return(-EINVAL);
}
/*
* eata_proc_info
* inout : decides on the direction of the dataflow and the meaning of the
- * variables
+ * variables
* buffer: If inout==FALSE data is beeing written to it else read from it
* *start: If inout==FALSE start of the valid data in the buffer
* offset: If inout==FALSE offset from the beginning of the imaginary file
- * from which we start writing into the buffer
+ * from which we start writing into the buffer
* length: If inout==FALSE max number of bytes to be written into the buffer
- * else number of bytes in the buffer
+ * else number of bytes in the buffer
*/
int eata_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
+ int hostno, int inout)
{
- Scsi_Device *scd;
+ Scsi_Device *scd, SDev;
struct Scsi_Host *HBA_ptr;
Scsi_Cmnd scmd;
+ char cmnd[10];
static u8 buff[512];
static u8 buff2[512];
hst_cmd_stat *rhcs, *whcs;
size = sprintf(buffer + len, "Host Bus: EISA\n");
len += size;
pos = begin + len;
+
} else {
+ memset(&SDev, 0, sizeof(Scsi_Device));
+ memset(&scmd, 0, sizeof(Scsi_Cmnd));
+
+ SDev.host = HBA_ptr;
+ SDev.id = HBA_ptr->this_id;
+ SDev.lun = 0;
+ SDev.channel = 0;
+
+ cmnd[0] = LOG_SENSE;
+ cmnd[1] = 0;
+ cmnd[2] = 0x33 + (3<<6);
+ cmnd[3] = 0;
+ cmnd[4] = 0;
+ cmnd[5] = 0;
+ cmnd[6] = 0;
+ cmnd[7] = 0x00;
+ cmnd[8] = 0x66;
+ cmnd[9] = 0;
- scmd.cmnd[0] = LOG_SENSE;
- scmd.cmnd[1] = 0;
- scmd.cmnd[2] = 0x33 + (3<<6);
- scmd.cmnd[3] = 0;
- scmd.cmnd[4] = 0;
- scmd.cmnd[5] = 0;
- scmd.cmnd[6] = 0;
- scmd.cmnd[7] = 0x00;
- scmd.cmnd[8] = 0x66;
- scmd.cmnd[9] = 0;
scmd.cmd_len = 10;
scmd.host = HBA_ptr;
+ scmd.device = &SDev;
scmd.target = HBA_ptr->this_id;
scmd.lun = 0;
scmd.channel = 0;
-
scmd.use_sg = 0;
- scmd.request_bufflen = 0x66;
- scmd.request_buffer = buff + 0x144;
- HBA_interpret = TRUE;
-
- eata_queue(&scmd, (void *) eata_scsi_done);
- while (internal_command_finished == FALSE)
- barrier();
+
+ /* Used for mutex if loading devices after boot */
+ scmd.request.sem = NULL;
+ scmd.request.dev = 0xffff; /* Mark busy */
+ scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66,
+ eata_scsi_done, 1 * HZ, 1);
+ /*
+ * Wait for command to finish. Use simple wait if we are
+ * booting, else do it right and use a mutex
+ */
+ if (current->pid == 0) {
+ while (scmd.request.dev != 0xfffe)
+ barrier();
+ } else if (scmd.request.dev != 0xfffe) {
+ struct semaphore sem = MUTEX_LOCKED;
+
+ scmd.request.sem = &sem;
+ down(&sem);
+
+ /* Hmm.. Have to ask about this one */
+ while (scmd.request.dev != 0xfffe) schedule();
+ }
+
size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt,
(cc->intt == TRUE)?"level":"edge");
len += size;
(sb->ext == TRUE)?"With external cable detection":"");
len += size;
pos = begin + len;
- size = sprintf(buffer + len, "SCSI channel expansion Module: %s installed\n",
+ size = sprintf(buffer + len, "SCSI channel expansion Module: %s present\n",
(bt->sx1 == TRUE)?"SX1 (one channel)":
((bt->sx2 == TRUE)?"SX2 (two channels)":"not"));
len += size;
(cc->srs == TRUE)?"":"not ");
len += size;
pos = begin + len;
- size = sprintf(buffer + len, " Type: %s\n",
+ size = sprintf(buffer + len, " Type: %s\n",
((cc->key == TRUE)?((bt->dmi == TRUE)?"integrated"
:((bt->dm4 == TRUE)?"DM401X"
:(bt->dm4k == TRUE)?"DM4000"
len += size;
pos = begin + len;
- size = sprintf(buffer + len, " Max array groups: %d\n",
+ size = sprintf(buffer + len, " Max array groups: %d\n",
(al->code == 0x0e)?al->max_groups:7);
len += size;
pos = begin + len;
- size = sprintf(buffer + len, " Max drives per RAID 0 array: %d\n",
+ size = sprintf(buffer + len, " Max drives per RAID 0 array: %d\n",
(al->code == 0x0e)?al->raid0_drv:7);
len += size;
pos = begin + len;
- size = sprintf(buffer + len, " Max drives per RAID 3/5 array: %d\n",
+ size = sprintf(buffer + len, " Max drives per RAID 3/5 array: %d\n",
(al->code == 0x0e)?al->raid35_drv:7);
len += size;
pos = begin + len;
- size = sprintf(buffer + len, "Cache Module: %sinstalled.\n",
+ size = sprintf(buffer + len, "Cache Module: %spresent.\n",
(cc->csh)?"":"not ");
len += size;
pos = begin + len;
- size = sprintf(buffer + len, " Type: %s\n",
+ size = sprintf(buffer + len, " Type: %s\n",
((cc->csh == TRUE)?((bt->cmi == TRUE)?"integrated"
:((bt->cm4 == TRUE)?"CM401X"
:((bt->cm4k == TRUE)?"CM4000"
len += size;
pos = begin + len;
}
- size = sprintf(buffer + len, "Timer Modification: %sinstalled\n",
+ size = sprintf(buffer + len, "Timer Mod.: %spresent\n",
(cc->tmr == TRUE)?"":"not ");
len += size;
pos = begin + len;
- size = sprintf(buffer + len, "NVRAM: %spresent\n",
+ size = sprintf(buffer + len, "NVRAM : %spresent\n",
(cc->nvr == TRUE)?"":"not ");
len += size;
pos = begin + len;
- size = sprintf(buffer + len, "SmartROM: %senabled\n",
- (bt->srom == TRUE)?"not ":"");
+ size = sprintf(buffer + len, "SmartROM : %sabled\n",
+ (bt->srom == TRUE)?"dis":"en");
len += size;
pos = begin + len;
- size = sprintf(buffer + len, "HBA indicates %salarm.\n",
- (bt->alrm == TRUE)?"":"no ");
+ size = sprintf(buffer + len, "Alarm : %s\n",
+ (bt->alrm == TRUE)?"on":"off");
len += size;
pos = begin + len;
if (pos > offset + length)
goto stop_output;
- scmd.cmnd[0] = LOG_SENSE;
- scmd.cmnd[1] = 0;
- scmd.cmnd[2] = 0x32 + (3<<6);
- scmd.cmnd[3] = 0;
- scmd.cmnd[4] = 0;
- scmd.cmnd[5] = 0;
- scmd.cmnd[6] = 0;
- scmd.cmnd[7] = 0x01;
- scmd.cmnd[8] = 0x44;
- scmd.cmnd[9] = 0;
+ cmnd[0] = LOG_SENSE;
+ cmnd[1] = 0;
+ cmnd[2] = 0x32 + (3<<6);
+ cmnd[3] = 0;
+ cmnd[4] = 0;
+ cmnd[5] = 0;
+ cmnd[6] = 0;
+ cmnd[7] = 0x01;
+ cmnd[8] = 0x44;
+ cmnd[9] = 0;
+
scmd.cmd_len = 10;
- scmd.host = HBA_ptr;
- scmd.target = HBA_ptr->this_id;
- scmd.lun = 0;
- scmd.channel = 0;
- scmd.use_sg = 0;
- scmd.request_bufflen = 0x144;
- scmd.request_buffer = buff2;
- HBA_interpret = TRUE;
+
+ /* Used for mutex if loading devices after boot */
+ scmd.request.sem = NULL;
+ scmd.request.dev = 0xffff; /* Mark busy */
- eata_queue(&scmd, (void *) eata_scsi_done);
- while (internal_command_finished == FALSE)
- barrier();
+ scsi_do_cmd (&scmd, cmnd, buff2, 0x144,
+ eata_scsi_done, 1 * HZ, 1);
+ /*
+ * Wait for command to finish. Use simple wait if we are
+ * booting, else do it right and use a mutex
+ */
+ if (current->pid == 0)
+ while (scmd.request.dev != 0xfffe)
+ barrier();
+ else if (scmd.request.dev != 0xfffe) {
+ struct semaphore sem = MUTEX_LOCKED;
+
+ scmd.request.sem = &sem;
+ down(&sem);
+
+ /* Hmm.. Have to ask about this one */
+ while (scmd.request.dev != 0xfffe) schedule();
+ }
swap_statistics(buff2);
rhcs = (hst_cmd_stat *)(buff2 + 0x2c);
SD(HBA_ptr)->reads[12] += rhcs->sizes[x];
SD(HBA_ptr)->writes[12] += whcs->sizes[x];
}
- size = sprintf(buffer + len, "Host Disk Command Statistics:\n"
- " Reads: Writes:\n");
+ size = sprintf(buffer + len, "Host<->Disk command statistics:\n"
+ " Reads: Writes:\n");
len += size;
pos = begin + len;
for (x = 0; x <= 10; x++) {
if(SD(HBA_ptr)->do_latency == TRUE) {
size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
- "Current timer resolution: 10ms\n"
- " Reads: Min:(ms) Max:(ms) Ave:(ms)\n");
+ "Current timer resolution: 10ms\n"
+ " Reads: Min:(ms) Max:(ms) Ave:(ms)\n");
len += size;
pos = begin + len;
for (x = 0; x <= 10; x++) {
size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n",
- 1 << x,
+ 1 << x,
SD(HBA_ptr)->reads_lat[x][0],
(SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10),
+ ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10),
SD(HBA_ptr)->reads_lat[x][2] * 10,
SD(HBA_ptr)->reads_lat[x][3] * 10 /
- ((SD(HBA_ptr)->reads_lat[x][0])
- ? SD(HBA_ptr)->reads_lat[x][0]:1));
+ ((SD(HBA_ptr)->reads_lat[x][0])
+ ? SD(HBA_ptr)->reads_lat[x][0]:1));
len += size;
pos = begin + len;
}
size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
SD(HBA_ptr)->reads_lat[11][0],
(SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10),
+ ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10),
SD(HBA_ptr)->reads_lat[11][2] * 10,
SD(HBA_ptr)->reads_lat[11][3] * 10 /
- ((SD(HBA_ptr)->reads_lat[x][0])
- ? SD(HBA_ptr)->reads_lat[x][0]:1));
+ ((SD(HBA_ptr)->reads_lat[x][0])
+ ? SD(HBA_ptr)->reads_lat[x][0]:1));
len += size;
pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if (pos > offset + length)
+ goto stop_output;
size = sprintf(buffer + len,
- " Writes: Min:(ms) Max:(ms) Ave:(ms)\n");
+ " Writes: Min:(ms) Max:(ms) Ave:(ms)\n");
len += size;
pos = begin + len;
for (x = 0; x <= 10; x++) {
size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n",
- 1 << x,
+ 1 << x,
SD(HBA_ptr)->writes_lat[x][0],
(SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
+ ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
SD(HBA_ptr)->writes_lat[x][2] * 10,
SD(HBA_ptr)->writes_lat[x][3] * 10 /
- ((SD(HBA_ptr)->writes_lat[x][0])
- ? SD(HBA_ptr)->writes_lat[x][0]:1));
+ ((SD(HBA_ptr)->writes_lat[x][0])
+ ? SD(HBA_ptr)->writes_lat[x][0]:1));
len += size;
pos = begin + len;
}
size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
SD(HBA_ptr)->writes_lat[11][0],
(SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
+ ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
SD(HBA_ptr)->writes_lat[11][2] * 10,
SD(HBA_ptr)->writes_lat[11][3] * 10/
- ((SD(HBA_ptr)->writes_lat[x][0])
- ? SD(HBA_ptr)->writes_lat[x][0]:1));
+ ((SD(HBA_ptr)->writes_lat[x][0])
+ ? SD(HBA_ptr)->writes_lat[x][0]:1));
len += size;
pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if (pos > offset + length)
+ goto stop_output;
}
scd = scsi_devices;
while (scd) {
if (scd->host == HBA_ptr) {
-
- size = sprintf(buffer + len,
- "Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
- scd->channel, scd->id, scd->lun);
- for (x = 0; x < 8; x++) {
- if (scd->vendor[x] >= 0x20)
- size += sprintf(buffer + len + size, "%c", scd->vendor[x]);
- else
- size += sprintf(buffer + len + size," ");
- }
- size += sprintf(buffer + len + size, " Model: ");
- for (x = 0; x < 16; x++) {
- if (scd->model[x] >= 0x20)
- size += sprintf(buffer + len + size, "%c", scd->model[x]);
- else
- size += sprintf(buffer + len + size, " ");
- }
- size += sprintf(buffer + len + size, " Rev: ");
- for (x = 0; x < 4; x++) {
- if (scd->rev[x] >= 0x20)
- size += sprintf(buffer + len + size, "%c", scd->rev[x]);
- else
- size += sprintf(buffer + len + size, " ");
- }
- size += sprintf(buffer + len + size, "\n");
-
- size += sprintf(buffer + len + size, " Type: %s ",
- scd->type < MAX_SCSI_DEVICE_CODE ?
- scsi_dev_types[(int)scd->type] : "Unknown " );
- size += sprintf(buffer + len + size, " ANSI"
- " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
- if (scd->scsi_level == 2)
- size += sprintf(buffer + len + size, " CCS\n");
- else
- size += sprintf(buffer + len + size, "\n");
+ proc_print_scsidevice(scd, buffer, &size, len);
len += size;
pos = begin + len;
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
- * indent-tabs-mode: nil
* tab-width: 8
* End:
*/
/* This is the pointer to the /proc/scsi code.
* It is only initialized to !=0 if the scsi code is present
*/
-extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start, off_t offset, int length, int inout);
-extern int dispatch_scsi_info(int ino, char *buffer, char **start, off_t offset, int length, int inout);
+extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start,
+ off_t offset, int length, int inout);
+extern int dispatch_scsi_info(int ino, char *buffer, char **start,
+ off_t offset, int length, int inout);
+
+extern void proc_print_scsidevice(Scsi_Device *scd, char *buffer,
+ int *size, int len);
/*
* As the scsi do command functions are intelligent, and may need to
while(SCpnt){
if(SCpnt->target == device->id &&
SCpnt->lun == device->lun) {
+ SCwait = SCpnt;
if(SCpnt->request.dev < 0) break;
}
SCpnt = SCpnt->next;
while(SCpnt){
if(SCpnt->target == device->id) {
if (SCpnt->lun == device->lun) {
+ SCwait = SCpnt;
if(found == NULL
&& SCpnt->request.dev < 0)
{
struct Scsi_Host *HBA_ptr;
int parameter[4];
char *p;
+ int size, len = 0;
+ off_t begin = 0;
+ off_t pos = 0;
scd = scsi_devices;
HBA_ptr = scsi_hostlist;
- if(inout == 0) /* We can only write to this file right now */
- return(-ENOSYS); /* This is still a no-op */
+ if(inout == 0) {
+ size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
+ len += size;
+ pos = begin + len;
+ while (HBA_ptr) {
+#if 0
+ size += sprintf(buffer+len,"scsi%2d: %s\n", (int) HBA_ptr->host_no, HBA_ptr->hostt->procname);
+ len += size;
+ pos = begin + len;
+#endif
+ scd = scsi_devices;
+ while (scd) {
+ if (scd->host == HBA_ptr) {
+ proc_print_scsidevice(scd, buffer, &size, len);
+ len += size;
+ pos = begin + len;
+
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if (pos > offset + length)
+ goto stop_output;
+ }
+ scd = scd->next;
+ }
+ HBA_ptr = HBA_ptr->next;
+ }
+
+ stop_output:
+ *start=buffer+(offset-begin); /* Start of wanted data */
+ len-=(offset-begin); /* Start slop */
+ if(len>length)
+ len = length; /* Ending slop */
+ return (len);
+ }
if(!buffer || length < 25 || strncmp("scsi", buffer, 4))
return(-EINVAL);
extern int max_scsi_hosts;
extern void build_proc_dir_entries(void);
+extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
+
extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
* information directly to the lowlevel driver.
*
* (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
- * Version: 0.99.6 last change: 95/07/04
+ * Version: 0.99.7 last change: 95/07/18
*
* generic command parser provided by:
* Andreas Heilwagen <crashcar@informatik.uni-koblenz.de>
return(cmdIndex);
}
+#define MAX_SCSI_DEVICE_CODE 10
+const char *const scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
+{
+ "Direct-Access ",
+ "Sequential-Access",
+ "Printer ",
+ "Processor ",
+ "WORM ",
+ "CD-ROM ",
+ "Scanner ",
+ "Optical Device ",
+ "Medium Changer ",
+ "Communications "
+};
+
+void proc_print_scsidevice(Scsi_Device *scd, char *buffer, int *size, int len)
+{
+ int x, y = *size;
+
+ y = sprintf(buffer + len,
+ "Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
+ scd->channel, scd->id, scd->lun);
+ for (x = 0; x < 8; x++) {
+ if (scd->vendor[x] >= 0x20)
+ y += sprintf(buffer + len + y, "%c", scd->vendor[x]);
+ else
+ y += sprintf(buffer + len + y," ");
+ }
+ y += sprintf(buffer + len + y, " Model: ");
+ for (x = 0; x < 16; x++) {
+ if (scd->model[x] >= 0x20)
+ y += sprintf(buffer + len + y, "%c", scd->model[x]);
+ else
+ y += sprintf(buffer + len + y, " ");
+ }
+ y += sprintf(buffer + len + y, " Rev: ");
+ for (x = 0; x < 4; x++) {
+ if (scd->rev[x] >= 0x20)
+ y += sprintf(buffer + len + y, "%c", scd->rev[x]);
+ else
+ y += sprintf(buffer + len + y, " ");
+ }
+ y += sprintf(buffer + len + y, "\n");
+
+ y += sprintf(buffer + len + y, " Type: %s ",
+ scd->type < MAX_SCSI_DEVICE_CODE ?
+ scsi_dev_types[(int)scd->type] : "Unknown " );
+ y += sprintf(buffer + len + y, " ANSI"
+ " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
+ if (scd->scsi_level == 2)
+ y += sprintf(buffer + len + y, " CCS\n");
+ else
+ y += sprintf(buffer + len + y, "\n");
+
+ *size = y;
+ return;
+}
/*
* Overrides for Emacs so that we get a uniform tabbing style.
X(kernel_scsi_ioctl),
X(need_isa_buffer),
X(request_queueable),
+#if defined(CONFIG_PROC_FS)
+ X(proc_print_scsidevice),
+#endif
/*
* These are here only while I debug the rest of the scsi stuff.
*/
/*
* name not found.
*/
-
+ brelse4(qbh);
return 0;
}
}
if (ino == PROC_SCSI_SCSI) {
- inode->i_mode = S_IFREG | S_IWUSR;
+ inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
inode->i_op = &proc_scsi_inode_operations;
return;
}
return;
}
-int _getitimer(int which, struct itimerval *value)
+static int _getitimer(int which, struct itimerval *value)
{
- register unsigned long val, interval;
+ register long val, interval;
switch (which) {
case ITIMER_REAL:
- val = current->it_real_value;
interval = current->it_real_incr;
+ val = 0;
+ if (del_timer(¤t->real_timer)) {
+ val = current->real_timer.expires;
+ add_timer(¤t->real_timer);
+ if (val <= 0)
+ val = interval;
+ }
break;
case ITIMER_VIRTUAL:
val = current->it_virt_value;
}
jiffiestotv(val, &value->it_value);
jiffiestotv(interval, &value->it_interval);
- return(0);
+ return 0;
}
asmlinkage int sys_getitimer(int which, struct itimerval *value)
X(scsi_devices),
X(gendisk_head), /* Needed for sd.c */
X(resetup_one_dev), /* Needed for sd.c */
+#if defined(CONFIG_PROC_FS)
+ X(proc_print_scsidevice),
+#endif
#else
/*
* With no scsi configured, we still need to export a few
}
#endif
if (p == &init_task) {
- printk("idle task may not sleep\n");
+ static int nr = 0;
+ if (nr < 5) {
+ nr++;
+ printk("idle task may not sleep\n");
+ }
return;
}
nr_running--;
#endif
#ifndef __HAVE_ARCH_STRCHR
-char * strchr(const char * s,char c)
+char * strchr(const char * s, int c)
{
- for(; *s != c; ++s)
+ for(; *s != (char) c; ++s)
if (*s == '\0')
return NULL;
return (char *) s;
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#ifndef __HAVE_ARCH_MEMSCAN
-void * memscan(void * addr, unsigned char c, size_t size)
+void * memscan(void * addr, int c, size_t size)
{
unsigned char * p = (unsigned char *) addr;