S: Boca Raton, Florida 33431-6588
S: USA
+N: David Gentzel
+E: gentzel@nova.enet.dec.com
+D: BusLogic driver and original UltraStor driver
+S: Whitfield Software Services
+S: 631 Idlewood Avenue
+S: Carnegie, Pennsylvania 15106-1126
+S: USA
+
N: Philip Gladstone
E: philipg@onsett.com
D: Kernel / timekeeping stuff
VERSION = 1
PATCHLEVEL = 1
-SUBLEVEL = 45
+SUBLEVEL = 46
ARCH = i386
if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
if [ -f $(INSTALL_PATH)/zSystem.map ]; then mv $(INSTALL_PATH)/zSystem.map $(INSTALL_PATH)/zSystem.old; fi
cat zImage > $(INSTALL_PATH)/vmlinuz
- cat zImage > $(INSTALL_PATH)/vmlinuz
cp zSystem.map $(INSTALL_PATH)/
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
entry start
start:
+! Bootlin depends on this being done early
+ mov ax,#0x01500
+ mov dl,#0x81
+ int 0x13
+
! Check signature at end of setup
mov ax,#SETUPSEG
mov ds,ax
bool 'Assume subnets are local' CONFIG_INET_SNARL y
bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
fi
-bool 'The IPX protocol' CONFIG_IPX y
+bool 'The IPX protocol' CONFIG_IPX n
+bool 'RPC connections to old BSD systems' CONFIG_I_AM_A_BROKEN_BSD_WEENIE n
#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
fi
Tests performed on an 80486 FPU showed results of lower accuracy. The
following table gives the results which were obtained with an AMD
-486DX2/66 (other tests indictate that an Intel 486DX produces
+486DX2/66 (other tests indicate that an Intel 486DX produces
identical results). The tests were basically the same as those used
to measure the emulator (the values, being random, were in general not
the same). The total number of tests for each instruction are given
if ( (st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
{
#ifdef PECULIAR_486
- /* This is wierd! */
+ /* This is weird! */
if (st0_ptr->sign == SIGN_POS)
setcc(SW_C3);
#endif PECULIAR_486
}
else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
{
- /* 32 bit displacment */
+ /* 32 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
offset += (signed) get_fs_long((unsigned long *) (*fpu_eip));
{
/* accumulatoro must contain 1.0 here, (actually, 0) but it
really doesn't matter what value we use because it will
- have neglibible effect in later calculations
+ have negligible effect in later calculations
*/
XSIG_LL(accum) = 0x8000000000000000LL;
accum.lsw = 0;
return 0;
/* This is a special case: see sec 16.2.5.1 of the 80486 book. */
- /* Masked respose is overflow to infinity. */
+ /* Masked response is overflow to infinity. */
templ = 0x7f800000;
}
else
a non-zero value is returned */
/* Overflow is signalled by a non-zero return value (in eax).
In the case of overflow, the returned significand always has the
- the largest possible value */
+ largest possible value */
int round_to_int(FPU_REG *r)
{
char very_big;
/*===========================================================================*/
/*
- A call to this function must be preceeded by a call to
+ A call to this function must be preceded by a call to
FPU_verify_area() to verify access to the 10 bytes at d
*/
static void write_to_extended(FPU_REG *rp, char *d)
| Australia. E-mail billm@vaxc.cc.monash.edu.au |
| |
| This code has four possible entry points. |
- | The following must be entered by a jmp intruction: |
+ | The following must be entered by a jmp instruction: |
| fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit. |
| |
| The _round_reg entry point is intended to be used by C code. |
printk("hd%c: read_intr: error = 0x%02x\n",dev+'a',hd_error);
}
bad_rw_intr();
+ cli();
hd_request();
return;
ok_to_read:
printk("hd:%c multwrite_intr: error = 0x%02x\n",dev+'a',hd_error);
}
bad_rw_intr();
+ cli();
hd_request();
}
printk("HD: write_intr: error = 0x%02x\n",hd_error);
}
bad_rw_intr();
+ cli();
hd_request();
return;
ok_to_write:
* Note: lockstate is used as index in the array key_map.
*/
struct kbd_struct {
- unsigned char ledstate; /* 3 bits */
+ unsigned char ledstate; /* 3 bits */
unsigned char default_ledstate;
+ unsigned char lockstate; /* 3 bits */
#define VC_SCROLLOCK 0 /* scroll-lock mode */
#define VC_NUMLOCK 1 /* numeric lock mode */
#define VC_CAPSLOCK 2 /* capslock mode */
- unsigned char lockstate; /* 4 bits - must be in 0..15 */
-#define VC_SHIFTLOCK KG_SHIFT /* shift lock mode */
-#define VC_ALTGRLOCK KG_ALTGR /* altgr lock mode */
-#define VC_CTRLLOCK KG_CTRL /* control lock mode */
-#define VC_ALTLOCK KG_ALT /* alt lock mode */
unsigned char modeflags;
#define VC_APPLIC 0 /* application key mode */
u_char type;
/* the XOR below used to be an OR */
- int shift_final = shift_state ^ kbd->lockstate;
+ int shift_final = shift_state ^ vc_kbd_lock(kbd,VC_CAPSLOCK);
key_code = key_map[shift_final][scancode];
type = KTYP(key_code);
if (type == KT_LETTER) {
type = KT_LATIN;
- if (vc_kbd_led(kbd,VC_CAPSLOCK))
- key_code = key_map[shift_final ^ (1<<KG_SHIFT)][scancode];
+ if (vc_kbd_lock(kbd,VC_CAPSLOCK))
+ key_code = key_map[shift_final][scancode];
}
(*key_handler[type])(key_code & 0xff, up_flag);
}
if (rep)
return;
chg_vc_kbd_led(kbd,VC_CAPSLOCK);
+ chg_vc_kbd_lock(kbd,VC_CAPSLOCK);
}
static void caps_on(void)
if (rep)
return;
set_vc_kbd_led(kbd,VC_CAPSLOCK);
+ set_vc_kbd_lock(kbd,VC_CAPSLOCK);
}
static void show_ptregs(void)
applkey('P', 1);
return;
}
- if (!rep) /* no autorepeat for numlock, ChN */
+ if (!rep) { /* no autorepeat for numlock, ChN */
chg_vc_kbd_led(kbd,VC_NUMLOCK);
+ chg_vc_kbd_lock(kbd,VC_NUMLOCK);
+ }
}
static void lastcons(void)
applkey(app_map[value], 1);
return;
}
-
- if (!vc_kbd_led(kbd,VC_NUMLOCK))
+ if (!vc_kbd_lock(kbd,VC_NUMLOCK))
switch (value) {
case KVAL(K_PCOMMA):
case KVAL(K_PDOT):
/* kludge... */
if (value == KVAL(K_CAPSSHIFT)) {
value = KVAL(K_SHIFT);
- if (!up_flag)
+ if (!up_flag) {
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
+ clr_vc_kbd_lock(kbd, VC_CAPSLOCK);
+ }
}
if (up_flag) {
read1 = read_mem(inode, file, buf, count);
if (read1 < 0)
return read1;
- read2 = vread(buf + read1, (char *) file->f_pos, count - read1);
+ read2 = vread(buf + read1, (char *) ((unsigned long) file->f_pos), count - read1);
if (read2 < 0)
return read2;
file->f_pos += read2;
/*
* Initialize the console device. This is called *early*, so
* we can't necessarily depend on lots of kernel help here.
- * Jus do some early initializations, and do the complex setup
+ * Just do some early initializations, and do the complex setup
* later.
*/
long console_init(long kmem_start, long kmem_end)
| ECNTRL_START, E33G_CNTRL);
/* This is the byte copy loop: it should probably be tuned for
- for speed once everything is working. I think it is possible
+ speed once everything is working. I think it is possible
to output 8 bytes between each check of the status bit. */
for(i = 0; i < count; i++) {
if (i % 8 == 0)
| ECNTRL_START, E33G_CNTRL);
/* This is the byte copy loop: it should probably be tuned for
- for speed once everything is working. */
+ speed once everything is working. */
for(i = 0; i < count; i++) {
if (i % 8 == 0)
while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
#if defined(SLIP) || defined(CONFIG_SLIP)
extern int slip_init(struct device *);
+
+#ifdef SL_SLIP_LOTS
+
+ static struct device slip15_dev={"sl15",0,0,0,0,15,0,0,0,0,NEXT_DEV,slip_init};
+ static struct device slip14_dev={"sl14",0,0,0,0,14,0,0,0,0,&slip15_dev,slip_init};
+ static struct device slip13_dev={"sl13",0,0,0,0,13,0,0,0,0,&slip14_dev,slip_init};
+ static struct device slip12_dev={"sl12",0,0,0,0,12,0,0,0,0,&slip13_dev,slip_init};
+ static struct device slip11_dev={"sl11",0,0,0,0,11,0,0,0,0,&slip12_dev,slip_init};
+ static struct device slip10_dev={"sl10",0,0,0,0,10,0,0,0,0,&slip11_dev,slip_init};
+ static struct device slip9_dev={"sl9",0,0,0,0,9,0,0,0,0,&slip10_dev,slip_init};
+ static struct device slip8_dev={"sl8",0,0,0,0,8,0,0,0,0,&slip9_dev,slip_init};
+ static struct device slip7_dev={"sl7",0,0,0,0,7,0,0,0,0,&slip8_dev,slip_init};
+ static struct device slip6_dev={"sl6",0,0,0,0,6,0,0,0,0,&slip7_dev,slip_init};
+ static struct device slip5_dev={"sl5",0,0,0,0,5,0,0,0,0,&slip6_dev,slip_init};
+ static struct device slip4_dev={"sl4",0,0,0,0,4,0,0,0,0,&slip5_dev,slip_init};
+# undef NEXT_DEV
+# define NEXT_DEV (&slip4_dev)
+#endif /* SL_SLIP_LOTS */
+
static struct device slip3_dev = {
"sl3", /* Internal SLIP driver, channel 3 */
0x0, /* recv memory end */
int i;
if (dev == NULL) {
- int alloc_size = sizeof(struct device) + sizeof("eth%d ")
+ int alloc_size = sizeof(struct device) + sizeof("eth%d ")
+ sizeof_private;
if (mem_startp && *mem_startp ) {
dev = (struct device *)*mem_startp;
} else
dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
memset(dev, 0, sizeof(alloc_size));
- dev->name = (char *)(dev + 1);
if (sizeof_private)
- dev->priv = dev->name + sizeof("eth%d ");
+ dev->priv = (void *) (dev + 1);
+ dev->name = sizeof_private + (char *)(dev + 1);
new_device = 1;
}
* Fixes:
* Alan Cox : Added slip mtu field.
* Matt Dillon : Printable slip (borrowed from net2e)
+ * Alan Cox : Added SL_SLIP_LOTS
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
*/
#define _LINUX_SLIP_H
/* SLIP configuration. */
+#ifndef SL_SLIP_LOTS
#define SL_NRUNIT 4 /* number of SLIP channels */
+#else
+#define SL_NRUNIT 16
+#endif
#define SL_MTU 296 /* 296; I am used to 600- FvK */
/* SLIP protocol characters. */
* drew@colorado.edu
* +1 (303) 666-5836
*
- * DISTRIBUTION REALEASE 6.
+ * DISTRIBUTION RELEASE 6.
*
* For more information, please consult
*
* $Log: NCR5380.c,v $
* Revision 1.5 1994/01/19 09:14:57 drew
* Fixed udelay() hack that was being used on DATAOUT phases
- * instead of a propper wait for the final handshake.
+ * instead of a proper wait for the final handshake.
*
* Revision 1.4 1994/01/19 06:44:25 drew
* *** empty log message ***
*/
/*
- * Furthur development / testing that should be done :
+ * Further development / testing that should be done :
* 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete
* code so that everything does the same thing that's done at the
* end of a pseudo-DMA read operation.
* adaptation to platforms like the Mac (Some of which use NCR5380's)
* more difficult than it has to be.
*
- * Also, many of the SCSI drivers were written before the command queing
+ * Also, many of the SCSI drivers were written before the command queuing
* routines were implemented, meaning their implementations of queued
* commands were hacked on rather than designed in from the start.
*
* each 5380 in the system - commands that haven't been issued yet,
* and commands that are currently executing. This means that an
* unlimited number of commands may be queued, letting
- * more commands propogate from the higher driver levels giving higher
- * througput. Note that both I_T_L and I_T_L_Q nexuses are supported,
- * allowing multiple commands to propogate all the way to a SCSI-II device
- * while a command is allready executing.
+ * more commands propagate from the higher driver levels giving higher
+ * throughput. Note that both I_T_L and I_T_L_Q nexuses are supported,
+ * allowing multiple commands to propagate all the way to a SCSI-II device
+ * while a command is already executing.
*
* To solve the multiple-boards-in-the-same-system problem,
* there is a separate instance structure for each instance
- * of a 5380 in the system. So, mutliple NCR5380 drivers will
+ * of a 5380 in the system. So, multiple NCR5380 drivers will
* be able to coexist with appropriate changes to the high level
* SCSI code.
*
* brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
* while doing long seek operations.
*
- * The workarround for this is to keep track of devices that have
+ * The workaround for this is to keep track of devices that have
* disconnected. If the device hasn't disconnected, for commands that
* should disconnect, we do something like
*
* on "time to data" would give the best results as long as short time
* to datas (ie, on the same track) were considered, however these
* broken devices are the exception rather than the rule and I'd rather
- * spend my time optomizing for the normal case.
+ * spend my time optimizing for the normal case.
*
* Architecture :
*
- * At the heart of the design is a corroutine, NCR5380_main,
+ * At the heart of the design is a coroutine, NCR5380_main,
* which is started when not running by the interrupt handler,
* timer, and queue command function. It attempts to establish
* I_T_L or I_T_L_Q nexuses by removing the commands from the
* will try to sleep.
*
* If a command has disconnected, eventually an interrupt will trigger,
- * calling NCR5380_intr() which will inturn call NCR5380_reselect
- * to restablish a nexus. This will run main if necessary.
+ * calling NCR5380_intr() which will in turn call NCR5380_reselect
+ * to reestablish a nexus. This will run main if necessary.
*
* On command termination, the done function will be called as
* appropriate.
* for commands that return with a CHECK CONDITION status.
*
* DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- * tracievers.
+ * transceivers.
*
* LINKED - if defined, linked commands are supported.
*
* rely on phase mismatch and EOP interrupts to determine end
* of phase.
*
- * SCSI2 - if defined, SCSI-2 tagged queing is used where possible
+ * SCSI2 - if defined, SCSI-2 tagged queuing is used where possible
*
* UNSAFE - leave interrupts enabled during pseudo-DMA transfers. You
* only really want to use this if you're having a problem with
*
* If this is not done, the routines will be defined as static functions
* with the NCR5380* names and the user must provide a globally
- * accessable wrapper function.
+ * accessible wrapper function.
*
* The generic driver is initialized by calling NCR5380_init(instance),
* after setting the appropriate host specific fields and ID. If the
#endif
/*
- * We need to have our corroutine active given these constraints :
+ * We need to have our coroutine active given these constraints :
* 1. The mutex flag, main_running, can only be set when the main
* routine can actually process data, otherwise SCSI commands
* will never get issued.
* even though it is only called in two places.
*
* So, the solution is to set the mutex in an inline wrapper for the
- * main corroutine, and have the main corroutine exit with interrupts
+ * main coroutine, and have the main coroutine exit with interrupts
* disabled after the final search through the queues so that no race
* conditions are possible.
*/
/*
* Function : int should_disconnect (unsigned char cmd)
*
- * Purpose : decide weather a commmand would normally disconnect or
+ * Purpose : decide weather a command would normally disconnect or
* not, since if it won't disconnect we should go to sleep.
*
* Input : cmd - opcode of SCSI command
* Returns : DISCONNECT_LONG if we should disconnect for a really long
* time (ie always, sleep, look for REQ active, sleep),
* DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
- * time-to-data dealy, DISCONNECT_NONE if this command would return
+ * time-to-data delay, DISCONNECT_NONE if this command would return
* immediately.
*
* Future sleep algorithms based on time to data can exploit
return 0;
}
-/* Doing something about unwanted rentrancy here might be useful */
+/* Doing something about unwanted reentrancy here might be useful */
void NCR5380_timer_fn(void) {
struct Scsi_Host *instance;
cli();
* Purpose : autoprobe for the IRQ line used by the NCR5380.
*
* Inputs : instance - pointer to this instance of the NCR5380 driver,
- * possible - bitmask of permissable interrupts.
+ * possible - bitmask of permissible interrupts.
*
* Returns : number of the IRQ selected, IRQ_NONE if no interrupt fired.
*
/*
* Function : void NCR5380_init (struct Scsi_Host *instance, flags)
*
- * Purpose : initializies *instance and corresponding 5380 chip,
+ * Purpose : initializes *instance and corresponding 5380 chip,
* with flags OR'd into the initial flags value.
*
* Inputs : instance - instantiation of the 5380 driver.
#ifndef AUTOSENSE
if ((instance->cmd_per_lun > 1) || instance->can_queue > 1))
printk("scsi%d : WARNING : support for multiple outstanding commands enabled\n"
- " without AUTOSENSE option, contigent alligence conditions may\n"
+ " without AUTOSENSE option, contingent allegiance conditions may\n"
" be incorrectly cleared.\n", instance->host_no);
#endif /* def AUTOSENSE */
/*
* Insert the cmd into the issue queue. Note that REQUEST SENSE
* commands are added to the head of the queue since any command will
- * clear the contingent allegience condition that exists and the
- * sense data is only guranteed to be valid while the condition exists.
+ * clear the contingent allegiance condition that exists and the
+ * sense data is only guaranteed to be valid while the condition exists.
*/
cli();
(cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
#endif
-/* Run the coroutine if it isn't allready running. */
+/* Run the coroutine if it isn't already running. */
run_main();
return 0;
}
/*
* Function : NCR5380_main (void)
*
- * Purpose : NCR5380_main is a corroutine that runs as long as more work can
+ * Purpose : NCR5380_main is a coroutine that runs as long as more work can
* be done on the NCR5380 host adapters in a system. Both
* NCR5380_queue_command() and NCR5380_intr() will try to start it
* in case it is not running.
*
* NOTE : NCR5380_main exits with interrupts *disabled*, the caller should
- * reenable them. This prevents rentrancy and kernel stack overflow.
+ * reenable them. This prevents reentrancy and kernel stack overflow.
*/
static void NCR5380_main (void) {
hostdata->issue_queue = (Scsi_Cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
- /* renable interrupts after finding one */
+ /* reenable interrupts after finding one */
sti();
/*
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
- * contingent alligence condition exists for the
+ * contingent allegiance condition exists for the
* entire unit.
*/
/*
* Function : void NCR5380_intr (int irq)
*
- * Purpose : handle interrupts, restablishing I_T_L or I_T_L_Q nexuses
+ * Purpose : handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
* from the disconnected queue, and restarting NCR5380_main()
* as required.
*
} else {
/*
* XXX the rest of the interrupt conditions should *only* occur during a
- * DMA transfer, which I haven't gotten arround to fixing yet.
+ * DMA transfer, which I haven't gotten around to fixing yet.
*/
#if defined(REAL_DMA)
int transfered;
if (!hostdata->connected)
- panic("scsi%d : recieved end of DMA interrupt with no connected cmd\n",
+ panic("scsi%d : received end of DMA interrupt with no connected cmd\n",
instance->hostno);
transfered = (hostdata->dmalen - NCR5380_dma_residual(instance));
* the command that is presently connected.
*
* Returns : -1 if selection could not execute for some reason,
- * 0 if selection succeeeded or failed because the target
+ * 0 if selection succeeded or failed because the target
* did not respond.
*
* Side effects :
/*
* The arbitration delay is 2.2us, but this is a minimum and there is
- * no maximum so we can safely sleep for ceil(2.2) usecs to accomodate
+ * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
* the integral nature of udelay().
*
*/
/*
* Raise ATN while SEL is true before BSY goes false from arbitration,
- * since this is the only way to gurantee that we'll get a MESSAGE OUT
+ * since this is the only way to guarantee that we'll get a MESSAGE OUT
* phase immediately after selection.
*/
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
+ * appropriate propagation delay has expired, and we're confusing
* a BSY signal from ourselves as the target's response to SELECTION.
*
* A small delay (the 'C++' frontend breaks the pipeline with an
- * unecessary jump, making it work on my 386-33/Trantor T128, the
+ * unnecessary jump, making it work on my 386-33/Trantor T128, the
* tighter 'C' code breaks and requires this) solves the problem -
* the 1 us delay is arbitrary, and only used because this delay will
* be the same on other platforms and since it works here, it should
/*
* XXX very interesting - we're seeing a bounce where the BSY we
- * asserted is being reflected / still asserted (propogation delay?)
+ * asserted is being reflected / still asserted (propagation delay?)
* and it's detecting as true. Sigh.
*/
if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
if (hostdata->targets_present & (1 << cmd->target)) {
- printk("scsi%d : wierdness\n", instance->host_no);
+ printk("scsi%d : weirdness\n", instance->host_no);
if (hostdata->restart_select)
printk("\trestart select\n");
#ifdef NDEBUG
* transfer phase should be a MESSAGE OUT phase so that we can send the
* IDENTIFY message.
*
- * If SCSI-II tagged queing is enabled, we also send a SIMPLE_QUEUE_TAG
+ * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
* message (2 bytes) with a tag ID that we increment with every command
* until it wraps back to 0.
*
* XXX - it turns out that there are some broken SCSI-II devices,
- * which claim to support tagged queing but fail when more than
+ * which claim to support tagged queuing but fail when more than
* some number of commands are issued at once.
*/
* what phase is expected, *count - pointer to number of
* bytes to transfer, **data - pointer to data pointer.
*
- * Returns : -1 when different phase is enterred without transfering
+ * Returns : -1 when different phase is entered without transferring
* maximum number of bytes, 0 if all bytes or transfered or exit
* is in same phase.
*
* what phase is expected, *count - pointer to number of
* bytes to transfer, **data - pointer to data pointer.
*
- * Returns : -1 when different phase is enterred without transfering
+ * Returns : -1 when different phase is entered without transferring
* maximum number of bytes, 0 if all bytes or transfered or exit
* is in same phase.
*
#endif
/*
- * FOO stuff. For some UNAPPARANT reason, I'm getting
- * watchdog timers fired on bootup for NO APPARANT REASON, meaning it's
+ * FOO stuff. For some UNAPPARENT reason, I'm getting
+ * watchdog timers fired on bootup for NO APPARENT REASON, meaning it's
* probably a timing problem.
*
* Since this is the only place I have back-to-back writes, perhaps this
#ifndef FOO
udelay(1);
#endif
- NCR5380_write(START_DMA_INITIATOR_RECIEVE_REG, 0);
+ NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
} else {
#ifndef FOO
udelay(1);
However, in order to handle scatter-reads, we must work around the
problem. The chosen fix is to DMA N-2 bytes, then check for the
condition before taking the NCR5380 out of DMA mode. One or two extra
- bytes are tranferred via PIO as necessary to fill out the original
+ bytes are transferred via PIO as necessary to fill out the original
request.
*/
if (p & SR_IO) {
if (!(foo = NCR5380_pread(instance, d, c - 1))) {
/*
- * We can't disable DMA mode after successfully transfering
+ * We can't disable DMA mode after successfully transferring
* what we plan to be the last byte, since that would open up
* a race condition where if the target asserted REQ before
* we got the DMA mode reset, the NCR5380 would have latched
* an additional byte into the INPUT DATA register and we'd
* have dropped it.
*
- * The workarround was to transfer one fewer bytes than we
+ * The workaround was to transfer one fewer bytes than we
* intended to with the pseudo-DMA read function, wait for
* the chip to latch the last byte, read it, and then disable
* pseudo-DMA mode.
* until ACK goes false. Since the NCR5380 won't lower ACK
* until DACK is asserted, which won't happen unless we twiddle
* the DMA port or we take the NCR5380 out of DMA mode, we
- * can gurantee that we won't handshake another extra
+ * can guarantee that we won't handshake another extra
* byte.
*/
}
/*
- * The preffered transfer method is going to be
+ * The prefered transfer method is going to be
* PSEUDO-DMA for systems that are strictly PIO,
* since we can let the hardware do the handshaking.
*
*/
NCR5380_write(TARGET_COMMAND_REG, 0);
- /* Enable reselect interupts */
+ /* Enable reselect interrupts */
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
/* Wait for bus free to avoid nasty timeouts */
while ((NCR5380_read(STATUS_REG) & SR_BSY) &&
* Unfortunately, some disks violate the SCSI spec and
* don't issue the required SAVE_POINTERS message before
* disconnecting, and we have to break spec to remain
- * compatable.
+ * compatible.
*/
case SAVE_POINTERS:
case RESTORE_POINTERS:
tmp = 0;
}
} else if (len) {
- printk("scsi%d: error recieving extended message\n",
+ printk("scsi%d: error receiving extended message\n",
instance->host_no);
tmp = 0;
} else {
/* Fall through to reject message */
/*
- * If we get something wierd that we aren't expecting,
+ * If we get something weird that we aren't expecting,
* reject it.
*/
default:
printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n",
instance->host_no, tmp, cmd->target, cmd->lun);
else
- printk("scsi%d: rejecting unknown extended message code %02x, legnth %d from target %d, lun %d\n",
+ printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n",
instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
msgout = MESSAGE_REJECT;
*
* Purpose : does reselection, initializing the instance->connected
* field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q
- * nexus has been restablished,
+ * nexus has been reestablished,
*
* Inputs : instance - this instance of the NCR5380.
*
/*
* Find the command corresponding to the I_T_L or I_T_L_Q nexus we
- * just restablished, and remove it from the disconnected queue.
+ * just reestablished, and remove it from the disconnected queue.
*/
* Inputs : instance - this instance of the NCR5380.
*
* Returns : pointer to the Scsi_Cmnd structure for which the I_T_L
- * nexus has been restablished, on failure NULL is returned.
+ * nexus has been reestablished, on failure NULL is returned.
*/
#ifdef REAL_DMA
* I_T_L_Q nexus associated with it, go into message out, and send
* an abort message.
*
- * This case is especially ugly. In order to resetablish the nexus, we
+ * This case is especially ugly. In order to reestablish the nexus, we
* need to call NCR5380_select(). The easiest way to implement this
* function was to abort if the bus was busy, and let the interrupt
* handler triggered on the SEL for reselect take care of lost arbitrations
return SCSI_ABORT_BUSY;
#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : nexus restablished.\n", instance->host_no);
+ printk("scsi%d : nexus reestablished.\n", instance->host_no);
#endif
msg = ABORT;
*
* We probably reached this point because of an unlikely race condition
* between the command completing successfully and the abortion code,
- * so we won't panic, but we will notify the user in case somethign really
+ * so we won't panic, but we will notify the user in case something really
* broke.
*/
* The contents of the OUTPUT DATA register are asserted on the bus when
* either arbitration is occuring or the phase-indicating signals (
* IO, CD, MSG) in the TARGET COMMAND register and the ASSERT DATA
- * bit in the INTITIATOR COMMAND register is set.
+ * bit in the INITIATOR COMMAND register is set.
*/
#define OUTPUT_DATA_REG 0 /* wo DATA lines on SCSI bus */
#define MR_TARGET 0x40 /* rw target mode */
#define MR_ENABLE_PAR_CHECK 0x20 /* rw enable parity checking */
#define MR_ENABLE_PAR_INTR 0x10 /* rw enable bad parity interrupt */
-#define MR_ENABLE_EOP_INTR 0x08 /* rw enabble eop interrupt */
+#define MR_ENABLE_EOP_INTR 0x08 /* rw enable eop interrupt */
#define MR_MONITOR_BSY 0x04 /* rw enable int on unexpected bsy fail */
#define MR_DMA_MODE 0x02 /* rw DMA / pseudo DMA mode */
#define MR_ARBITRATE 0x01 /* rw start arbitration */
*/
#define INPUT_DATA_REG 6 /* ro */
-/* Write any value to this register to start a DMA recieve */
-#define START_DMA_TARGET_RECIEVE_REG 6 /* wo */
+/* Write any value to this register to start a DMA receive */
+#define START_DMA_TARGET_RECEIVE_REG 6 /* wo */
/* Read this register to clear interrupt conditions */
#define RESET_PARITY_INTERRUPT_REG 7 /* ro */
-/* Write any value to this register to start an ini mode DMA recieve */
-#define START_DMA_INITIATOR_RECIEVE_REG 7 /* wo */
+/* Write any value to this register to start an ini mode DMA receive */
+#define START_DMA_INITIATOR_RECEIVE_REG 7 /* wo */
#ifdef NCR53C400
#define C400_CONTROL_STATUS_REG -8 /* rw */
#define CSR_53C80_REG 0x80 /* ro 5380 registers busy */
#define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
#define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */
-#define CSR_53C80_INTR 0x10 /* rw Enable 53c80 interupts */
-#define CSR_SHARED_INTR 0x08 /* rw Interupt sharing */
+#define CSR_53C80_INTR 0x10 /* rw Enable 53c80 interrupts */
+#define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */
#define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Is Host buffer ready */
#define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer read */
#define CSR_GATED_53C80_IRQ 0x01 /* ro Last block xferred */
#ifndef ASM
struct NCR5380_hostdata {
- NCR5380_implementation_fields; /* implmenentation specific */
+ NCR5380_implementation_fields; /* implementation specific */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected
to, so we can call a select
if (count > limit) count = limit;
if ((count & 1) || (((unsigned) ptr) & 1))
- panic ("scsi%d : attmpted unaligned DMA transfer\n", instance->host_no);
+ panic ("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
cli();
disable_dma(instance->dma_channel);
clear_dma_ff(instance->dma_channel);
BASICS
The driver is generic. The state of a drive is not modified when the
-driver is initalized or a device is opened. The mode parameters of the
+driver is initialized or a device is opened. The mode parameters of the
drive can be modified with ioctls. The driver supports fixed and
variable block size (within buffer limits). Both the auto-rewind
(minor equals device number) and non-rewind devices (minor is 128 +
};
#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
-/* possible i/o adresses for the AIC-6260 */
+/* possible i/o addresses for the AIC-6260 */
static unsigned short ports[] =
{
0x340, /* default first */
/* disconnected target is trying to reconnect.
Only possible, if we have disconnected nexuses and
- nothing is occuping the bus.
+ nothing is occupying the bus.
*/
if( TESTHI( SSTAT0, SELDI ) &&
disconnected_SC &&
sti();
#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- printk("issueing command, ");
+ printk("issuing command, ");
#endif
current_SC->SCp.phase = in_selection;
break;
case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
- thean was allocated by the Data Length field or the sum of the
+ than was allocated by the Data Length field or the sum of the
Scatter / Gather Data Length fields. */
case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
/* Quick and dirty test for presence of the card. */
if(inb(STATUS(bse)) == 0xff) return 0;
- /* Reset the adapter. I ought to make a hard reset, but it's not really nessesary */
+ /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */
/* DEB(printk("aha1542_test_port called \n")); */
/* READ */
#define STATUS(base) base
#define STST 0x80 /* Self Test in Progress */
-#define DIAGF 0x40 /* Internal Diagonostic Failure */
+#define DIAGF 0x40 /* Internal Diagnostic Failure */
#define INIT 0x20 /* Mailbox Initialization Required */
#define IDLE 0x10 /* SCSI Host Adapter Idle */
#define CDF 0x08 /* Command/Data Out Port Full */
{
if ( (status[1]&0x18) || status_word.sc ) /*Additional info available*/
{
- /* Use the supplied info for futher diagnostics */
+ /* Use the supplied info for further diagnostics */
switch ( status[2] )
{
case 0x12:
I when I wrote it, but the Adaptec Spec says the card is so fast,
that this problem virtually never occurs so I've kept it. We
do printk a warning first, so that you'll know if it happens.
- In practive the only time we've seen this message is when some-
+ In practice the only time we've seen this message is when some-
thing else is in the driver was broken, like _makecode(), or
when a scsi device hung the scsi bus. Even under these conditions,
The loop actually only cycled < 3 times (we instrumented it). */
* BT-747D - 747S + differential termination.
* BT-757S - 747S + WIDE SCSI.
* BT-757D - 747D + WIDE SCSI.
+ * BT-946C - PCI bus-master FAST SCSI. (??? Nothing else known.)
*
* Should you require further information on any of these boards, BusLogic
* can be reached at (408)492-9090.
*
* This driver SHOULD support all of these boards. It has only been tested
- * with a 747S. An earlier version was tested with a 445S.
+ * with a 747S and 445S.
*
* Places flagged with a triple question-mark are things which are either
* unfinished, questionable, or wrong.
#endif
};
-#define BIOS_TRANSLATION_6432 0 /* Default case */
-#define BIOS_TRANSLATION_25563 1 /* Big disk case */
+#define BIOS_TRANSLATION_DEFAULT 0 /* Default case */
+#define BIOS_TRANSLATION_BIG 1 /* Big disk (> 1G) case */
struct hostdata {
unsigned char bus_type;
static void buslogic_interrupt(int junk)
{
void (*my_done)(Scsi_Cmnd *) = NULL;
- int errstatus, mbistatus = 0, number_serviced, found;
+ int errstatus, mbistatus = MBX_NOT_IN_USE, number_serviced, found;
size_t mbi, mbo = 0;
struct Scsi_Host *shpnt;
Scsi_Cmnd *sctmp;
mb[mbi].status);
#endif
- if (mbistatus == 0x03) /* ??? 0x03 == Aborted CCB not found. */
+ if (mbistatus == MBX_COMPLETION_NOT_FOUND)
continue;
#if BUSLOGIC_DEBUG
#endif
/* ??? more error checking left out here */
- if (mbistatus != 1)
+ if (mbistatus != MBX_COMPLETION_OK)
/* ??? This is surely wrong, but I don't know what's right. */
errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
else
/* We only need a DMA channel for ISA boards. Some other types of boards
(such as the 747S) have an option to report a DMA channel even though
- none is used (for compatability with Adaptec drivers which require a
+ none is used (for compatibility with Adaptec drivers which require a
DMA channel). We ignore this. */
if (*bus_type == 'A')
switch (*dma) {
static int get_translation(unsigned int base)
{
- /* ??? This is wrong if disk is configured for > 1G mapping.
- Unfortunately, unlike UltraStor, I see know way of determining whether
- > 1G mapping has been enabled. */
- return BIOS_TRANSLATION_6432;
+ /* ??? Unlike UltraStor, I see no way of determining whether > 1G mapping
+ has been enabled. However, it appears that BusLogic uses a mapping
+ scheme which varies with the disk size when > 1G mapping is enabled.
+ For disks <= 1G, this mapping is the same regardless of the setting of
+ > 1G mapping. Therefore, we should be safe in always assuming that > 1G
+ mapping has been enabled. */
+ return BIOS_TRANSLATION_BIG;
}
/* Query the board to find out the model. */
WAIT_UNTIL(INTERRUPT(base), CMDC);
INTR_RESET(base);
-#if 1 /* ??? Temporary */
+#if 1 /* ??? Temporary */
buslogic_printk("Inquiry Bytes: %02X %02X %02X %02X\n",
inquiry_result[0], inquiry_result[1],
inquiry_result[2], inquiry_result[3]);
/* ??? If we can dynamically allocate the mailbox arrays, I'll
probably bump up this number. */
shpnt->hostt->can_queue = BUSLOGIC_MAILBOXES;
- /*shpnt->base = ???;*/
+ /* No known way to determine BIOS base address, but we don't
+ care since we don't use it anyway. */
+ shpnt->base = NULL;
shpnt->io_port = base;
shpnt->dma_channel = dma;
shpnt->irq = irq;
HOSTDATA(shpnt)->bios_translation = trans;
- if (trans == BIOS_TRANSLATION_25563)
+ if (trans == BIOS_TRANSLATION_BIG)
buslogic_printk("Using extended bios translation.\n");
HOSTDATA(shpnt)->last_mbi_used = 2 * BUSLOGIC_MAILBOXES - 1;
HOSTDATA(shpnt)->last_mbo_used = BUSLOGIC_MAILBOXES - 1;
if (HOSTDATA(shpnt)->sc[i]
&& !HOSTDATA(shpnt)->sc[i]->device->soft_reset) {
#if 0
- HOSTDATA(shpnt)->mb[i].status = 1; /* Indicate ready to
- restart... */
+ HOSTDATA(shpnt)->mb[i].status
+ = MBX_ACTION_START; /* Indicate ready to restart... */
#endif
count++;
}
int buslogic_biosparam(Disk *disk, int dev, int *ip)
{
- int size = disk->capacity;
- int translation_algorithm;
-
- translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
- /* ??? Should this be > 1024, or >= 1024? Enquiring minds want to know. */
- if ((size >> 11) > 1024
- && translation_algorithm == BIOS_TRANSLATION_25563) {
- /* Please verify that this is the same as what DOS returns */
- ip[0] = 255;
- ip[1] = 63;
- ip[2] = size / 255 / 63;
+ /* ??? This truncates. Should we round up to next MB? */
+ unsigned int mb = disk->capacity >> 11;
+
+ /* ip[0] == heads, ip[1] == sectors, ip[2] == cylinders */
+ if (HOSTDATA(disk->device->host)->bios_translation == BIOS_TRANSLATION_BIG
+ && mb > 1024) {
+ if (mb > 4096) {
+ ip[0] = 256;
+ ip[1] = 64;
+ ip[2] = mb >> 3;
+/* if (ip[2] > 1024)
+ ip[2] = 1024; */
+ } else if (mb > 2048) {
+ ip[0] = 256;
+ ip[1] = 32;
+ ip[2] = mb >> 2;
+ } else {
+ ip[0] = 128;
+ ip[1] = 32;
+ ip[2] = mb >> 1;
+ }
} else {
ip[0] = 64;
ip[1] = 32;
- ip[2] = size >> 11;
+ ip[2] = mb;
+/* if (ip[2] > 1024)
+ ip[2] = 1024; */
}
-/* if (ip[2] > 1024)
- ip[2] = 1024; */
return 0;
}
/* READ */
#define STATUS(base) (base)
#define DACT 0x80 /* Diagnostic Active */
-#define DFAIL 0x40 /* Diagonostic Failure */
+#define DFAIL 0x40 /* Diagnostic Failure */
#define INREQ 0x20 /* Initialization Required */
#define HARDY 0x10 /* Host Adapter Ready */
#define CPRBSY 0x08 /* Command/Parameter Register Busy */
#define CMD_HA_OPTIONS 0x21 /* Host Adapter Options */
#define CMD_INITEXTMB 0x81 /* Initialize Extended Mailbox */
#define CMD_INQEXTSETUP 0x8D /* Inquire Extended Set-up Information */
-#define CMD_WRITE_INQ_BUF 0x9A /* Write Inquery Data Buffer
+#define CMD_WRITE_INQ_BUF 0x9A /* Write Inquiry Data Buffer
(Target Mode Only) */
-#define CMD_READ_INQ_BUF 0x9B /* Read Inquery Data Buffer
+#define CMD_READ_INQ_BUF 0x9B /* Read Inquiry Data Buffer
(Target Mode Only) */
#define MBX_NOT_IN_USE 0x00
/* 29-2d */ unknown, "Write (10)", "Seek (10)", unknown, unknown,
/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal",
/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position",
-/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Deffect Data",
+/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data",
/* 38-3c */ unknown, "Compare","Copy Verify", "Write Buffer", "Read Buffer",
/* 3d-39 */ unknown, "Read Long", unknown,
};
static const char * statuses[] = {
/* 0-4 */ "Good", "Check Condition", "Condition Good", unknown, "Busy",
/* 5-9 */ unknown, unknown, unknown, "Intermediate Good", unknown,
-/* a-d */ "Interemediate Good", unknown, "Reservation Conflict", unknown,
+/* a-d */ "Intermediate Good", unknown, "Reservation Conflict", unknown,
/* e-f */ unknown, unknown,
};
#endif
{0x11,0x04,D|W|O,"Unrecovered read error - auto reallocate failed"},
{0x11,0x05,W|R|O,"L-ec uncorrectable error"},
{0x11,0x06,W|R|O,"Circ unrecovered error"},
- {0x11,0x07,W|O,"Data resychronization error"},
+ {0x11,0x07,W|O,"Data resynchronization error"},
{0x11,0x08,T,"Incomplete block read"},
{0x11,0x09,T,"No gap found"},
{0x11,0x0A,D|T|O,"Miscorrected error"},
static const char *extended_msgs[] = {
/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
-/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Reqeust"
+/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
};
#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs) / sizeof (const char *))
NOTES ON USER DEFINABLE OPTIONS:
- DEBUG: This turns on the printing of various debug informaiton.
+ DEBUG: This turns on the printing of various debug information.
ENABLE_PARITY: This turns on SCSI parity checking. With the current
driver, all attached devices must support SCSI parity. If none of your
values.
DO_DETECT: This activates some old scan code which was needed before the
- high level drivers got fixed. If you are having toruble with the driver,
+ high level drivers got fixed. If you are having trouble with the driver,
turning this on should not hurt, and might help. Please let me know if
this is the case, since this code will be removed from future drivers.
{ "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
{ "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
- /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGANTURE
+ /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
Also, fix the disk geometry code for your signature and send your
changes for faith@cs.unc.edu. Above all, do *NOT* change any old
signatures!
* used on the LILO command line to override the defaults.
*
* 2. With the GENERIC_NCR5380_OVERRIDE compile time define. This is
- * specified as an array of address, irq tupples. Ie, for
+ * specified as an array of address, irq tuples. Ie, for
* one board at the default 0xcc000 address, IRQ5, no dma, I could
* say -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE}}
*
* -1 should be specified for no or DMA interrupt, -2 to autoprobe for an
- * IRQ line if overriden on the command line.
+ * IRQ line if overridden on the command line.
*/
/*
*
* Purpose : LILO command line initialization of the overrides array,
*
- * Inputs : str - unused, ints - array of integer paramters with ints[0]
+ * Inputs : str - unused, ints - array of integer parameters with ints[0]
* equal to the number of ints.
*
*/
}
/*
- * Function : int generic_NCR5380_detect(Scsi_Host_Templace * tpnt)
+ * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
*
* Purpose : initializes generic NCR5380 driver based on the
* command line / compile time port and irq definitions.
* The scsi host entries should be in the order you wish the
* cards to be detected. A driver may appear more than once IFF
* it can deal with being detected (and therefore initialized)
- * with more than one simulatenous host number, can handle being
- * rentrant, etc.
+ * with more than one simultaneous host number, can handle being
+ * reentrant, etc.
*
* They may appear in any order, as each SCSI host is told which host number it is
* during detection.
retval->hostt = tpnt;
retval->next = NULL;
#ifdef DEBUG
- printk("Register %x %x: %d %d\n", retval, retval->hostt, i, j);
+ printk("Register %x %x: %d\n", retval, retval->hostt, j);
#endif
/* The next three are the default values which can be overridden
*/
#ifndef _HOSTS_H
- #define _HOSTS_H
+#define _HOSTS_H
/*
$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.h,v 1.3 1993/09/24 12:21:00 drew Exp drew $
/*
The Scsi_Host_Template type has all that is needed to interface with a SCSI
- host in a device independant matter. There is one entry for each different
+ host in a device independent matter. There is one entry for each different
type of host adapter that is supported on the system.
*/
functions to queue commands because things are not guaranteed
to be set up yet. The detect routine can send commands to
the host adapter as long as the program control will not be
- passed to scsi.c in the processesing of the command. Note
+ passed to scsi.c in the processing of the command. Note
especially that scsi_malloc/scsi_free must not be called.
*/
/*
This determines if we will use a non-interrupt driven
or an interrupt driven scheme, It is set to the maximum number
- of simulataneous commands a given host adapter will accept.
+ of simultaneous commands a given host adapter will accept.
*/
int can_queue;
In many instances, especially where disconnect / reconnect are
supported, our host also has an ID on the SCSI bus. If this is
the case, then it must be reserved. Please set this_id to -1 if
- your settup is in single initiator mode, and the host lacks an
+ your setup is in single initiator mode, and the host lacks an
ID.
*/
extern void scsi_unregister(struct Scsi_Host * i);
#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-#endif
struct Scsi_Device_Template
{
extern struct Scsi_Device_Template sg_template;
int scsi_register_device(struct Scsi_Device_Template * sdpnt);
+
+#endif
* used on the LILO command line to override the defaults.
*
* 3. With the PAS16_OVERRIDE compile time define. This is
- * specified as an array of address, irq tupples. Ie, for
+ * specified as an array of address, irq tuples. Ie, for
* one board at the default 0x388 address, IRQ10, I could say
* -DPAS16_OVERRIDE={{0x388, 10}}
* NOTE: Untested.
0x3c00, /* STATUS_REG ro, SELECT_ENABLE_REG wo */
0x3c01, /* BUS_AND_STATUS_REG ro, START_DMA_SEND_REG wo */
0x3c02, /* INPUT_DATA_REGISTER ro, (N/A on PAS16 ?)
- * START_DMA_TARGET_RECIEVE_REG wo
+ * START_DMA_TARGET_RECEIVE_REG wo
*/
0x3c03, /* RESET_PARITY_INTERRUPT_REG ro,
- * START_DMA_INITIATOR_RECIEVE_REG wo
+ * START_DMA_INITIATOR_RECEIVE_REG wo
*/
};
&& !force_irq )
{
printk( "pas16: WARNING: Can't use same irq as sound "
- "driver -- interrupts diabled\n" );
+ "driver -- interrupts disabled\n" );
/* Set up the drive parameters, disable 5380 interrupts */
outb( 0x4d, io_port + SYS_CONFIG_4 );
}
*
* Purpose : LILO command line initialization of the overrides array,
*
- * Inputs : str - unused, ints - array of integer paramters with ints[0]
+ * Inputs : str - unused, ints - array of integer parameters with ints[0]
* equal to the number of ints.
*
*/
* Function : int pas16_detect(Scsi_Host_Template * tpnt)
*
* Purpose : detects and initializes PAS16 controllers
- * that were autoprobed, overriden on the LILO command line,
+ * that were autoprobed, overridden on the LILO command line,
* or specified at compile time.
*
* Inputs : tpnt - template for this SCSI adapter.
printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
/* Disable 5380 interrupts, leave drive params the same */
outb( 0x4d, io_port + SYS_CONFIG_4 );
+ outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
}
#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
/*
* Function : int pas16_biosparam(Disk *disk, int dev, int *ip)
*
- * Purpose : Generates a BIOS / DOS compatable H-C-S mapping for
+ * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
* the specified device / size.
*
* Inputs : size = size of device in sectors (512 bytes), dev = block device
* major / minor, ip[] = {heads, sectors, cylinders}
*
- * Returns : allways 0 (success), initializes ip
+ * Returns : always 0 (success), initializes ip
*
*/
P_DATA_REG_OFFSET);
register i = len;
- while ( inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY );
+ while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) );
- for (; i; --i)
- *d++ = (unsigned char) inb(reg);
+ insb( reg, d, i );
if ( inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
- printk("scsi%d : watchdog timer fired in NCR5480_pread()\n",
+ printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
instance->host_no);
return -1;
} else
register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
register i = len;
- while ( ( inb( instance->io_port + P_STATUS_REG_OFFSET ) ) & P_ST_RDY );
- for (; i; --i)
- outb( *s++, reg );
+ while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) );
+
+ outsb( reg, s, i );
if (inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
- printk("scsi%d : watchdog timer fired in NCR5480_pwrite()\n",
+ printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
instance->host_no);
return -1;
} else
/*
* Function : const char *pas16_info(void)
*
- * Purpose : provide furthur information about this driver.
+ * Purpose : provide further information about this driver.
*
* Returns : an empty string.
*/
#ifndef PAS16_H
#define PAS16_H
-#define PAS16_PUBLIC_RELEASE 2
+#define PAS16_PUBLIC_RELEASE 3
#define PDEBUG_INIT 0x1
#define PDEBUG_TRANSFER 0x2
* The Pro Audio Spectrum boards are I/O mapped. They use a Zilog 5380
* SCSI controller, which is the equivalent of NCR's 5380. "Pseudo-DMA"
* architecture is used, where a PAL drives the DMA signals on the 5380
- * allowing fast, blind transfers with propper handshaking.
+ * allowing fast, blind transfers with proper handshaking.
*/
/* The Time-out Counter register is used to safe-guard against a stuck
- * bus (in the case of RDY driven hadnshake) or a stuck byte (if 16-Bit
+ * bus (in the case of RDY driven handshake) or a stuck byte (if 16-Bit
* DMA conversion is used). The counter uses a 28.224MHz clock
* divided by 14 as its clock source. In the case of a stuck byte in
* the holding register, an interrupt is generated (and mixed with the
# XXX - replace references to the *_810 constants with general constants
# assigned at compile time based on chip type.
-# Table of operatoor encodings
+# Table of operator encodings
# XXX - NCR53c710 only implements
# move (nop) = 0x00_00_00_00
# or = 0x02_00_00_00
# the index is the symbol name,
# and the contents a white space
# delimited list of address,size
- # tupples where size is in bytes.
+ # tuples where size is in bytes.
@code = (); # Array of 32 bit words for SIOP
$need_data = 0;
if ($conditional =~ /^ATN\s*(.*)/i) {#
die "$0 : syntax error in line $lineno : $_
- WHEN conditional is incompatable with ATN
+ WHEN conditional is incompatible with ATN
" if (!$allow_atn);
$code[$address] |= 0x00_02_00_00;
$conditional = $1;
} else {
die
"$0 : syntax error in $lineno : $_
- WITH CARRY option is incompatable with the $op operator.
+ WITH CARRY option is incompatible with the $op operator.
";
}
}
}
#
-# NCR assembler outputs label patches in the form of indecies into
+# NCR assembler outputs label patches in the form of indices into
# the code.
#
printf OUTPUT "unsigned long ".$prefix."LABELPATCHES[] = {\n";
/*
global variables :
- scsi_devices an array of these specifing the address for each
+ scsi_devices an array of these specifying the address for each
(host, id, LUN)
*/
Scsi_Cmnd * last_cmnd = NULL;
/*
- * As the scsi do command functions are inteligent, and may need to
+ * As the scsi do command functions are intelligent, and may need to
* redo a command, we need to keep track of the last command
* executed on each one.
*/
}
/*
- * Accomodate drivers that want to sleep when they should be in a polling
+ * Accommodate drivers that want to sleep when they should be in a polling
* loop.
*/
/*
We will use a queued command if possible, otherwise we will emulate the
- queing and calling of completion function ourselves.
+ queuing and calling of completion function ourselves.
*/
#ifdef DEBUG
printk("internal_cmnd (host = %d, target = %d, command = %08x, buffer = %08x, \n"
/*
scsi_do_cmd sends all the commands out to the low-level driver. It
handles the specifics required for each low level driver - ie queued
- or non queud. It also prevents conflicts when different high level
+ or non queued. It also prevents conflicts when different high level
drivers go for the same host at the same time.
*/
/*
We must prevent reentrancy to the lowlevel host driver. This prevents
it - we enter a loop until the host we want to talk to is not busy.
- Race conditions are prevented, as interrupts are disabled inbetween the
+ Race conditions are prevented, as interrupts are disabled in between the
time we check for the host being not busy, and the time we mark it busy
ourselves.
*/
}
break;
default:
- panic("scsi: unsupported message byte %d recieved\n", msg_byte(result));
+ panic("scsi: unsupported message byte %d received\n", msg_byte(result));
}
break;
case DID_TIME_OUT:
caller should deal with any error messages or status returned on the
next call.
- This will not be called rentrantly for a given host.
+ This will not be called reentrantly for a given host.
*/
/*
void scsi_init_free(char * ptr, unsigned int size)
-{ /* FIXME - not right. We need to comare addresses to see whether this was
+{ /* FIXME - not right. We need to compare addresses to see whether this was
kmalloc'd or not */
if((unsigned int) ptr < scsi_loadable_module_flag) {
kfree(ptr);
}
/*
- scsi_dev_init() is our initialization routine, which inturn calls host
+ scsi_dev_init() is our initialization routine, which in turn calls host
initialization, bus scanning, and sd/st initialization routines. It
should be called from main().
*/
#define SET_LIMITS 0x33
#define PRE_FETCH 0x34
#define READ_POSITION 0x34
-#define SYNCRONIZE_CACHE 0x35
+#define SYNCHRONIZE_CACHE 0x35
#define LOCK_UNLOCK_CACHE 0x36
#define READ_DEFECT_DATA 0x37
#define COMPARE 0x39
lsb msb
status msg host code
- Our errors returned by OUR driver, NOT SCSI message. Orr'd with
+ Our errors returned by OUR driver, NOT SCSI message. Or'd with
SCSI message passed back to driver <IF any>.
*/
unsigned lockable:1; /* Able to prevent media removal */
unsigned borken:1; /* Tell the Seagate driver to be
painfully slow on this device */
- unsigned tagged_supported:1; /* Supports SCSI-II tagged queing */
- unsigned tagged_queue:1; /*SCSI-II tagged queing enabled */
+ unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */
+ unsigned tagged_queue:1; /*SCSI-II tagged queuing enabled */
unsigned disconnect:1; /* can disconnect */
unsigned soft_reset:1; /* Uses soft reset option */
unsigned char current_tag; /* current tag */
#define msg_byte(result) (((result) >> 8) & 0xff)
#define host_byte(result) (((result) >> 16) & 0xff)
#define driver_byte(result) (((result) >> 24) & 0xff)
-#define sugestion(result) (driver_byte(result) & SUGGEST_MASK)
+#define suggestion(result) (driver_byte(result) & SUGGEST_MASK)
#define sense_class(sense) (((sense) >> 4) & 0x7)
#define sense_error(sense) ((sense) & 0xf)
unsigned underflow; /* Return error if less than this amount is
transfered */
- unsigned transfersize; /* How much we are guranteed to transfer with
+ unsigned transfersize; /* How much we are guaranteed to transfer with
each SCSI transfer (ie, between disconnect /
reconnects. Probably == sector size */
*/
if (driver_byte(result) != 0) {
- if (sugestion(result) == SUGGEST_REMAP) {
+ if (suggestion(result) == SUGGEST_REMAP) {
#ifdef REMAP
/*
Not yet implemented. A read will fail after being remapped,
/* If we had an ILLEGAL REQUEST returned, then we may have
performed an unsupported command. The only thing this should be would
-be a ten byte read where only a six byte read was supportted. Also,
-on a system where READ CAPACITY failed, we mave have read past the end
+be a ten byte read where only a six byte read was supported. Also,
+on a system where READ CAPACITY failed, we have have read past the end
of the disk.
*/
accept another command. If we find one, then we queue it. This can
make a big difference on systems with more than one disk drive. We want
to have the interrupts off when monkeying with the request list, because
- otherwise the kernel might try and slip in a request inbetween somewhere. */
+ otherwise the kernel might try and slip in a request in between somewhere. */
if (!SCpnt && sd_template.nr_dev > 1){
struct request *req1;
/* Wake up a process waiting for device*/
/*
- * The SCSI standard says "READ CAPACITY is necessary for self confuring software"
+ * The SCSI standard says "READ CAPACITY is necessary for self configuring software"
* While not mandatory, support of READ CAPACITY is strongly encouraged.
* We used to die if we couldn't successfully do a READ CAPACITY.
* But, now we go on about our way. The side effects of this are
/*
* Configuration :
* To use without BIOS -DOVERRIDE=base_address -DCONTROLLER=FD or SEAGATE
- * -DIRQ will overide the default of 5.
+ * -DIRQ will override the default of 5.
* Note: You can now set these options from the kernel's "command line".
* The syntax is:
*
* -DFAST or -DFAST32 will use blind transfers where possible
*
* -DARBITRATE will cause the host adapter to arbitrate for the
- * bus for better SCSI-II compatability, rather than just
+ * bus for better SCSI-II compatibility, rather than just
* waiting for BUS FREE and then doing its thing. Should
* let us do one command per Lun when I integrate my
* reorganization changes into the distribution sources.
*
- * -DSLOW_HANDSHAKE will allow compatability with broken devices that don't
+ * -DSLOW_HANDSHAKE will allow compatibility with broken devices that don't
* handshake fast enough (ie, some CD ROM's) for the Seagate
* code.
*
{"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
/*
- * However, future domain makes several incompatable SCSI boards, so specific
+ * However, future domain makes several incompatible SCSI boards, so specific
* signatures must be used.
*/
* Wait for a low->high transition before continuing with that
* transfer. If we timeout, continue anyways. We don't need
* a long timeout, because REQ should only be asserted until the
- * corresponding ACK is recieved and processed.
+ * corresponding ACK is received and processed.
*
* Note that we can't use the system timer for this, because of
* resolution, and we *really* can't use the timer chip since
/*
* Ok, we now have a count for .25 seconds. Convert to a
- * count per second and divide by transer rate in K.
+ * count per second and divide by transfer rate in K.
*/
borken_calibration = (count * 4) / (SLOW_RATE*1024);
printk("Base address overridden to %x, controller type is %s\n",
base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
#endif
-#else /* OVERIDE */
+#else /* OVERRIDE */
/*
* To detect this card, we simply look for the signature
* from the BIOS version notice in all the possible locations
- * of the ROM's. This has a nice sideeffect of not trashing
+ * of the ROM's. This has a nice side effect of not trashing
* any register locations that might be used by something else.
*
* XXX - note that we probably should be probing the address
base_address = (void *) seagate_bases[i];
controller_type = signatures[j].type;
}
-#endif /* OVERIDE */
+#endif /* OVERRIDE */
} /* (! controller_type) */
tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
/*
* We work it differently depending on if this is is "the first time,"
- * or a reconnect. If this is a reselct phase, then SEL will
+ * or a reconnect. If this is a reselect phase, then SEL will
* be asserted, and we must skip selection / arbitration phases.
*/
* target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
*
* After ARBITRATION phase is completed, only SEL, BSY, and the
- * target ID are asserted. A valid initator ID is not on the bus
+ * target ID are asserted. A valid initiator ID is not on the bus
* until IO is asserted, so we must wait for that.
*/
clock = jiffies + 10;
*
* Note : the Seagate ST-01/02 product manual says that we should
* twiddle the DATA register before the control register. However,
- * this does not work reliably so we do it the other way arround.
+ * this does not work reliably so we do it the other way around.
*
* Probably could be a problem with arbitration too, we really should
* try this with a SCSI protocol or logic analyzer to see what is
CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
/*
- * If we are reconecting, then we must send an IDENTIFY message in
+ * If we are reconnecting, then we must send an IDENTIFY message in
* response to MSGOUT.
*/
switch (reselect) {
reselect = CAN_RECONNECT;
goto connect_loop;
#if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
- printk("scsi%d : sent ABORT message to cancle incorrect I_T_L nexus.\n", hostno);
+ printk("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
#endif
#endif /* LINKED */
#if (DEBUG & DEBUG_LINKED)
hostno);
#endif
/*
- * We also will need to adjust status to accomodate intermediate conditions.
+ * We also will need to adjust status to accommodate intermediate conditions.
*/
if ((status == INTERMEDIATE_GOOD) ||
(status == INTERMEDIATE_C_GOOD))
cmd[5] = 0;
/*
- * We are transfering 0 bytes in the out direction, and expect to get back
+ * We are transferring 0 bytes in the out direction, and expect to get back
* 24 bytes for each mode page.
*/
/*
* Now, we need to do a sanity check on the geometry to see if it is
- * BIOS compatable. The maximum BIOS geometry is 1024 cylinders *
+ * BIOS compatible. The maximum BIOS geometry is 1024 cylinders *
* 256 heads * 64 sectors.
*/
*/
/*
- An SG device is accessed by writting "packets" to it, the replies
+ An SG device is accessed by writing "packets" to it, the replies
are then read using the read call. The same header is used for
reply, just ignore reply_len field.
*/
accept another command. If we find one, then we queue it. This can
make a big difference on systems with more than one disk drive. We want
to have the interrupts off when monkeying with the request list, because
- otherwise the kernel might try and slip in a request inbetween somewhere. */
+ otherwise the kernel might try and slip in a request in between somewhere. */
if (!SCpnt && sr_template.nr_dev > 1){
struct request *req1;
* used on the LILO command line to override the defaults.
*
* 3. With the T128_OVERRIDE compile time define. This is
- * specified as an array of address, irq tupples. Ie, for
+ * specified as an array of address, irq tuples. Ie, for
* one board at the default 0xcc000 address, IRQ5, I could say
* -DT128_OVERRIDE={{0xcc000, 5}}
*
*
* Purpose : LILO command line initialization of the overrides array,
*
- * Inputs : str - unused, ints - array of integer paramters with ints[0]
+ * Inputs : str - unused, ints - array of integer parameters with ints[0]
* equal to the number of ints.
*
*/
* 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,
+ * that were autoprobed, overridden on the LILO command line,
* or specified at compile time.
*
* Inputs : tpnt - template for this SCSI adapter.
/*
* Function : int t128_biosparam(Disk * disk, int dev, int *ip)
*
- * Purpose : Generates a BIOS / DOS compatable H-C-S mapping for
+ * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
* the specified device / size.
*
* Inputs : size = size of device in sectors (512 bytes), dev = block device
* major / minor, ip[] = {heads, sectors, cylinders}
*
- * Returns : allways 0 (success), initializes ip
+ * Returns : always 0 (success), initializes ip
*
*/
/*
* Function : const char *t128_info(void)
*
- * Purpose : provide furthur information about this driver.
+ * Purpose : provide further information about this driver.
*
* Returns : an empty string.
*/
* equivalent (my sample board had part second sourced from ZILOG).
* NCR's recommended "Pseudo-DMA" architecture is used, where
* a PAL drives the DMA signals on the 5380 allowing fast, blind
- * transfers with propper handshaking.
+ * transfers with proper handshaking.
*/
/*
#define T_STATUS_REG_OFFSET 0x1c20 /* ro */
#define T_ST_BOOT 0x80 /* Boot switch */
-#define T_ST_S3 0x40 /* User setable switches, */
+#define T_ST_S3 0x40 /* User settable switches, */
#define T_ST_S2 0x20 /* read 0 when switch is on, 1 off */
#define T_ST_S1 0x10
#define T_ST_PS2 0x08 /* Set for Microchannel 228 */
#define T_ST_RDY 0x04 /* 5380 DRQ */
#define T_ST_TIM 0x02 /* indicates 40us watchdog timer fired */
-#define T_ST_ZERO 0x01 /* Allways zero */
+#define T_ST_ZERO 0x01 /* Always zero */
#define T_5380_OFFSET 0x1d00 /* 8 registers here, see NCR5380.h */
return FALSE;
}
- /* Final consistancy check, verify previous info. */
+ /* Final consistency check, verify previous info. */
if (config.subversion != U34F)
if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: consistancy check failed\n");
+ printk("US14F: detect: consistency check failed\n");
#endif
return FALSE;
}
* ( as close as different hardware allows on a lowlevel-driver :-) )
*
* Revised (and renamed) by John Boyd <boyd@cis.ohio-state.edu> to
- * accomodate Eric Youngdale's modifications to scsi.c. Nov 1992.
+ * accommodate Eric Youngdale's modifications to scsi.c. Nov 1992.
*
* Additional changes to support scatter/gather. Dec. 1992. tw/jb
*
* Unfortunately, I have no idea how to properly use some of these commands,
* as the OEM manual does not make it clear. I have not been able to use
* enable/disable unsolicited interrupts or the reset commands with any
- * discernable effect whatsoever. I think they may be related to certain
+ * discernible effect whatsoever. I think they may be related to certain
* ICB commands, but again, the OEM manual doesn't make that clear.
*/
#define NO_OP 0 /* NO-OP toggles CMD_RDY bit in ASC_STAT */
- MIDI recording for SB and SB Pro. (Untested).
- Some other fixes.
- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
-- Implemented better detection for OPL-3. This should be usefull if you
+- Implemented better detection for OPL-3. This should be useful if you
have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
This version is backward compatible with the version 2.X. All programs
compiled with sys/soundcard.h of v2.X should work without problems.
PROGRAMS COMPILED WITH THE sys/soundcard.h OF THIS VERSION WILL NOT
-WORK WITH v2.X DRIVER. BE CAREFULL WHEN DISTRIBUTING BINARIES COMPILED
+WORK WITH v2.X DRIVER. BE CAREFUL WHEN DISTRIBUTING BINARIES COMPILED
FOR THIS VERSION.
Contributors
------------
This driver contains code by several contributors. In addition several other
-persons have given usefull suggestions. The following is a list of major
+persons have given useful suggestions. The following is a list of major
contributors. (I could have forgotten some names.)
Craig Metz 1/2 of the PAS16 Mixer and PCM support
let's skip this step. To be serious, the sound driver belongs
to linux/drivers/sound.
-- To build the device files you need to run the enclosed shell scrip
+- To build the device files you need to run the enclosed shell script
(see below).
- If you are installing a separately distributed version, copy the
sound=0x2220Id,0x138800 (remember to set the IRQ and DMA)
or if you have SB16 or SB16ASP, you have to use the following:
- (use the same IRQ (the I colums) in all three places. The
+ (use the same IRQ (the I columns) in all three places. The
the D is the 16 bit DMA channel (5 to 7) and the d is
the 8 bit one (1 or 3). The X is the 2nd digit of the
midi IO address (3 or 0)).
cat /dev/sndstat
-and look at the output. It should display some usefull info about the
+and look at the output. It should display some useful info about the
driver configuration. If there is no /dev/sndstat
(/dev/sndstat: No such file or directory), ensure that you have executed the
soundinstall script (at the end of this file). The message:
- /dev/???????: No such device.
You have not booted with a kernel containing the driver or the I/O address
-configuration doesn't match your hardaware.
+configuration doesn't match your hardware.
- The module player (str) plays just a second and then stops completely.
You have incorrect IRQ settings (usual with SB cards).
UltraSound card. (If you already have GUS, you should use gmod and not the
str). If the DSP_BUFFSIZE in the sound/local.h is less than (nr_channels*
speed_in_Hz * (bits/8))/2, it could explain the pausing problem. Also check
-that the turbo swich is on and don't run applications like weather forecasting
+that the turbo switch is on and don't run applications like weather forecasting
on background. Sometimes (very rarely) an IRQ conflict can cause similar
problems with SB cards.
If you want to play modules on a 386sx while recompiling the world, buy a GUS.
----------------- cut here ------------------------------
#!/bin/sh
#
-# soudinstall
+# soundinstall
#
#
# Create the devices
VoxWare v3.0
------------
-This is a PROTOTYPE of the VoxWare v3.0 to be relased late 94.
+This is a PROTOTYPE of the VoxWare v3.0 to be released late 94.
All features of v2.5 should work as earlier. There could be some
omissions but they are unintentional. I started this version thread
Even this is a prototype, there should not be any fatal bugs. The
prototype just means that I don't have implemented all features
-completely. Mainly in the /dev/sequener2 driver.
+completely. Mainly in the /dev/sequencer2 driver.
For example recording from /dev/sequencer2 won't work
with other cards than a full features MPU-401 or clones. As well the
way how the MIDI controllers are handled will change.
/dev/midi##
-----------
-This interface should be usefull for applications like MIDI sysex librarians.
+This interface should be useful for applications like MIDI sysex librarians.
There are (currently) no timing features so making music could be impossible.
There are as many /dev/midi## devices as there are MIDI ports in the system.
If this ioctl is called with mode=1, the interface is put to the intelligent
(coprocessor) mode. NOTE! The MIDI port will be reset when this ioctl is called.
It could have some strange effects if not called immediately after open. This
-vall returns EINVAL if the midi port doesn't support the MPU-401 intelligent
+call returns EINVAL if the midi port doesn't support the MPU-401 intelligent
mode.
ioctl(fd, SNDCTL_MIDI_MPUCMD, &cmdstruct) is valid only if the MIDI port
data Buffer for the command arguments and returned
data.
-Be extremely carefull with the nr_args and nr_returns fields. They
+Be extremely careful with the nr_args and nr_returns fields. They
must match the command. An incorrect value will put the card and
the driver out of sync. Refer to the MPU-401/MQX-32M documentation for further
-datails.
+details.
/dev/sequencer. Both kind of devices are accessed using the SEQ_START_NOTE()
like macros. The voice number parameters of the API macros have been redefined
to denote MIDI channels. This means that the driver allocates voices for
-the channels automaticly (this is a responsibility/right of an application
+the channels automatically (this is a responsibility/right of an application
with /dev/sequencer). The result is that a SEQ_START_NOTE() macro has
similar effects for a synth channel than on a MIDI port. This kind of
solution provides better device independence than the /dev/sequencer. The
- The new interface is used much like the ordinary /dev/sequencer. The
event format is new so you have to use the API macros defined in the
-sys/soundcard.h. The interface is will propably change before the final 3.0
+sys/soundcard.h. The interface will probably change before the final 3.0
release but using the API macros should ensure compatibility in source level.
The new event format is not recognized by version 2.X so don't try to
distribute binaries compiled with soundcard.h of v3.X.
-- The basic API useage is similar to the current one. There are some new
+- The basic API usage is similar to the current one. There are some new
macros but the older ones should work as earlier. The most important
incompatibility is that the /dev/sequencer2 driver allocates voices itself.
The other one is that the application must send SEQ_START_TIMER() as it's
set_speed (ad1848_info * devc, int arg)
{
/*
- * The sampling speed is encoded in the least significant nible of I8. The
+ * The sampling speed is encoded in the least significant nibble of I8. The
* LSB selects the clock source (0=24.576 MHz, 1=16.9344 Mhz) and other
* three bits select the divisor (indirectly):
*
ad_write (devc, 8, fs);
/*
- * Write to I8 starts resyncronization. Wait until it completes.
+ * Write to I8 starts resynchronization. Wait until it completes.
*/
timeout = 10000;
while (timeout > 0 && INB (devc->base) == 0x80)
ad_write (devc, 28, fs);
/*
- * Write to I28 starts resyncronization. Wait until it completes.
+ * Write to I28 starts resynchronization. Wait until it completes.
*/
timeout = 10000;
while (timeout > 0 && INB (devc->base) == 0x80)
{
FILE *sf = fopen ("synth-ld.h", "w");
- fprintf (sf, "/* automaticaly generated by configure */\n");
+ fprintf (sf, "/* automatically generated by configure */\n");
fprintf (sf, "unsigned char pss_synth[] = {\n");
while (1)
{
{
FILE *sf = fopen ("synth-ld.h", "w");
- fprintf (sf, "/* automaticaly generated by configure */\n");
+ fprintf (sf, "/* automatically generated by configure */\n");
fprintf (sf, "unsigned char pss_synth[1];\n"
"#define pss_synthLen 0\n");
fclose (sf);
if (selected_options & B (OPT_UART6850))
{
fprintf (stderr, "\nI/O base for 6850 UART Midi?\n"
- "Be carefull. No defaults.\n"
+ "Be careful. No defaults.\n"
"Enter the 6850 UART I/O base: ");
num = ask_value ("%x", 0);
{0}; /*
* Primitive way to allocate
* such a large array.
- * Needs dynamic run-time alloction.
+ * Needs dynamic run-time allocation.
*/
static void
sz = sr * nc * sz;
/*
- * Compute a buffer size for time not exeeding 1 second.
+ * Compute a buffer size for time not exceeding 1 second.
* Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
* of sound (using the current speed, sample size and #channels).
*/
else
{
/*
- * The process has specified the buffer sice with SNDCTL_DSP_SETFRAGMENT or
- * the buffer sice computation has already been done.
+ * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
+ * the buffer size computation has already been done.
*/
if (dmap->fragment_size > audio_devs[dev]->buffsize)
dmap->fragment_size = audio_devs[dev]->buffsize;
}
if (dmap->subdivision != 0 ||
- dmap->fragment_size)/* Loo late to change */
+ dmap->fragment_size)/* Too late to change */
return RET_ERROR (EINVAL);
if (fact > MAX_REALTIME_FACTOR)
return RET_ERROR (EIO);
if (dmap->subdivision != 0 ||
- dmap->fragment_size)/* Loo late to change */
+ dmap->fragment_size)/* Too late to change */
return RET_ERROR (EINVAL);
bytes = fact & 0xffff;
2a) If the fragment gets played before the application writes a new
- one, the device will be stoppen and restarted which causes a click.
+ one, the device will be stopped and restarted which causes a click.
When the process calls write next time, it will be processes as
in step 1.
the process blocks for at most the time required to play a
buffer fragment.
-This method syncronizes the process and the audio device together
-automaticly. The process will block at most the 'fragment_time'. Usually
+This method synchronizes the process and the audio device together
+automatically. The process will block at most the 'fragment_time'. Usually
less, depending on how much it needs time to do other things. The maximum
delay between writing a byte and the time when it finally plays is
at most 3 times the 'fragment_time'.
ioctl(NDCTL_DSP_SPEED); /* And #channels & #bits if required */
/*
- * Query the actual fragment sice since the driver may refuse
+ * Query the actual fragment size since the driver may refuse
* the requested one (unlikely but possible?)
*/
*/
offs += sample_ptrs[sample]; /*
- * Begin offsess + offset to DRAM
+ * Begin offset + offset to DRAM
*/
for (n = 0; n < l; n++)
*/
offs += sample_ptrs[sample]; /*
- * Begin offsess + offset to DRAM
+ * Begin offset + offset to DRAM
*/
for (n = 0; n < l; n++)
*
* The percussive mode is implemented in the left side only.
*
- * With the above exeptions the both sides can be operated independently.
+ * With the above exceptions the both sides can be operated independently.
*
* A 4 OP voice can be created by setting the corresponding
* bit at offset 4 of the right side.
/* DISABLE_INTR is used to disable interrupts.
These macros store the current flags to the (unsigned long) variable given
- as a parameter. RESTORE_INTR returns the interrupt ebable bit to state
+ as a parameter. RESTORE_INTR returns the interrupt enable bit to state
before DISABLE_INTR or ENABLE_INTR */
#define DISABLE_INTR(flags) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
#define OPERATION_MODE_1 0xEF8B /* R Control */
#define O_M_1_CDROM_TYPE 0x03 /* R CD-ROM 3=SCSI, 2=Sony, 0=no CD-ROM interface */
- #define O_M_1_FM_TYPE 0x04 /* R FM 1=sterero, 0=mono FM chip */
+ #define O_M_1_FM_TYPE 0x04 /* R FM 1=stereo, 0=mono FM chip */
#define O_M_1_PCM_TYPE 0x08 /* R PCM 1=16-bit Codec, 0=8-bit DAC */
#define OPERATION_MODE_2 0xFF8B /* R Control */
#define O_M_2_PCS_ENABLED 0x02 /* R PC speaker PC speaker emulation 1=enabled, 0=disabled */
if (bits == P_M_MV508_BASS || bits == P_M_MV508_TREBLE)
{ /*
- * Bass and trebble are mono devices
+ * Bass and treble are mono devices
*/
pas_write (P_M_MV508_ADDRESS | bits, PARALLEL_MIXER);
pas_write (left, PARALLEL_MIXER);
tmp = pas_read (FILTER_FREQUENCY);
/*
- * Set anti-aliasing filters according to sample rate. You reall *NEED*
+ * Set anti-aliasing filters according to sample rate. You really *NEED*
* to enable this feature for all normal recording unless you want to
* experiment with aliasing effects.
* These filters apply to the selected "recording" source.
/*
* sound/patmgr.c
*
- * The patch maneger interface for the /dev/sequencer
+ * The patch manager interface for the /dev/sequencer
*
* Copyright by Hannu Savolainen 1993
*
make the pss card to emulate the SB stuff.
I have provided a simple interface to the PSS unlike the
- DOG version. to download a new algorithim just cat it to
+ DOG version. to download a new algorithm just cat it to
/dev/pss 14,9.
You really need to rebuild this with the synth.ld file
and everything will be okay.
- At first I was going to wory about applications that were using
+ At first I was going to worry about applications that were using
the sound stuff and disallow the use of /dev/pss. But for
now I figured it doesn't matter.
Probably everything else can be done via mmap
- Oh if you want to develope code for the ADSP-21xx or Program the
+ Oh if you want to develop code for the ADSP-21xx or Program the
1848 just send me mail and I will hook you up.
marc.hoffman@analog.com
{
int i, limit;
- limit = GET_TIME () + 10; /* The timeout is 0.1 secods */
+ limit = GET_TIME () + 10; /* The timeout is 0.1 seconds */
/*
* Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
* called while interrupts are disabled. This means that the timer is
/*_____ pss_checkint
This function tests an interrupt number to see if
- it is availible. It takes the interrupt button
+ it is available. It takes the interrupt button
as it's argument and returns TRUE if the interrupt
is ok.
*/
pss_outpw (pss_base + PSS_CONFIG, val);
break;
default:
- printk ("unknown interupt selected. %d\n", intNum);
+ printk ("unknown interrupt selected. %d\n", intNum);
return 0;
}
pss_outpw (configAddress, val);
break;
default:
- printk ("pss_setint unkown int\n");
+ printk ("pss_setint unknown int\n");
}
}
/* The following is a simple device driver for the pss.
- All I really care about is comunication to and from the pss.
+ All I really care about is communication to and from the pss.
The ability to reinitialize the <synth.ld> This will be
- default when release is choosen.
+ default when release is chosen.
SNDCTL_PSS_DOWNLOAD:
where a write operation would effectively
download a new ld.
- 14,0x09 -- /dev/psecho would open up a comunication path to the
+ 14,0x09 -- /dev/psecho would open up a communication path to the
esc614 asic. Given the ability to send
- messages to the asic and recive messages too.
+ messages to the asic and receive messages too.
All messages would get read and written in the
same manner. It would be up to the application
/* This is going to be used to implement
waiting on messages sent from the DSP and to the
- DSP when comunication is used via the pss directly.
+ DSP when communication is used via the pss directly.
- We need to find out if the pss can generate a diffrent
- interupt other than the one it has been setup for.
+ We need to find out if the pss can generate a different
+ interrupt other than the one it has been setup for.
This way we can carry on a conversation with the pss
- on a seprate chanel. This would be usefull for debugging. */
+ on a separate channel. This would be useful for debugging. */
pss_select (int dev, struct fileinfo * file, int sel_type, select_table * wait)
{
unsigned long limit;
limit = GET_TIME () + HZ / 10;/*
- * The timeout is 0.1 secods
+ * The timeout is 0.1 seconds
*/
/*
if (!(src & 1))
return; /*
- * Not a DSP interupt
+ * Not a DSP interrupt
*/
}
#endif
* future version of this driver.
*/
-extern int sb_dsp_ok; /* Set to 1 atfer successful initialization */
+extern int sb_dsp_ok; /* Set to 1 after successful initialization */
extern int sbc_base;
extern int sb_midi_mode;
/*
* The seq_mode gives the operating mode of the sequencer:
* 1 = level1 (the default)
- * 2 = level2 (extended capabilites)
+ * 2 = level2 (extended capabilities)
*/
#define SEQ_1 1
return;
if (seq_mode == SEQ_2)
- if (synth_devs[dev]->alloc_voice)
- voice = find_voice (dev, chn, note);
-
- if (cmd == MIDI_NOTEON && parm == 0)
{
- cmd = MIDI_NOTEOFF;
- parm = 64;
+ if (synth_devs[dev]->alloc_voice)
+ voice = find_voice (dev, chn, note);
+
+ if (cmd == MIDI_NOTEON && parm == 0)
+ {
+ cmd = MIDI_NOTEOFF;
+ parm = 64;
+ }
}
switch (cmd)
{
case MIDI_NOTEON:
- if (note > 127)
+ if (note > 127 && note != 255)
return;
if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
#define SND_DEV_STATUS 6 /* /dev/sndstat */
/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-#define SND_DEV_SEQ2 8 /* /dev/sequecer, level 2 interface */
+#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
#define SND_DEV_PSS SND_DEV_SNDPROC
{
int blocksize, blocksize_bits, i, j;
int block, blocks;
- int offset;
+ loff_t offset;
int chars;
int written = 0;
int cluster_list[4];
offset = filp->f_pos & (blocksize-1);
if (blk_size[MAJOR(dev)])
- size = (blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
+ size = ((loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
else
size = INT_MAX;
while (count>0) {
int block_read(struct inode * inode, struct file * filp, char * buf, int count)
{
unsigned int block;
- unsigned int offset;
+ loff_t offset;
int blocksize;
int blocksize_bits, i;
unsigned int blocks, rblocks, left;
struct buffer_head * buflist[NBUF];
struct buffer_head * bhreq[NBUF];
unsigned int chars;
- unsigned int size;
+ loff_t size;
unsigned int dev;
int read;
offset = filp->f_pos;
if (blk_size[MAJOR(dev)])
- size = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
+ size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
else
size = INT_MAX;
* 2 kernel space kernel space
*
* We do this by playing games with the fs segment register. Since it
- * it is expensive to load a segment register, we try to avoid calling
+ * is expensive to load a segment register, we try to avoid calling
* set_fs() unless we absolutely have to.
*/
unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
static int ext_readdir(struct inode * inode, struct file * filp,
struct dirent * dirent, int count)
{
- unsigned int offset,i;
+ unsigned int i;
+ off_t offset;
char c;
struct buffer_head * bh;
struct ext_dir_entry * de;
while (offset < 1024 && filp->f_pos < inode->i_size) {
if (de->rec_len < 8 || de->rec_len % 8 != 0 ||
de->rec_len < de->name_len + 8 ||
- (de->rec_len + filp->f_pos - 1) / 1024 > (filp->f_pos / 1024)) {
+ (de->rec_len + (off_t) filp->f_pos - 1) / 1024 > ((off_t) filp->f_pos / 1024)) {
printk ("ext_readdir: bad dir entry, skipping\n");
- printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
+ printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n",
inode->i_dev, inode->i_ino, offset, de->rec_len, de->name_len);
filp->f_pos += 1024-offset;
if (filp->f_pos > inode->i_size)
#endif
j = sb->u.ext_sb.s_firstfreeinodenumber;
if (efi->next > sb->u.ext_sb.s_ninodes) {
- printk ("efi->next = %d\n", efi->next);
+ printk ("efi->next = %ld\n", efi->next);
panic ("ext_new_inode: bad inode number in free list\n");
}
sb->u.ext_sb.s_firstfreeinodenumber = efi->next;
wait_on_buffer(bh);
if (bh->b_req && !bh->b_uptodate)
{
- printk ("IO error syncing ext inode [%04x:%08x]\n",
+ printk ("IO error syncing ext inode [%04x:%08lx]\n",
inode->i_dev, inode->i_ino);
err = -1;
}
de->rec_len < de->name_len + 8 ||
(((char *) de) + de->rec_len-1 >= BLOCK_SIZE+bh->b_data)) {
printk ("ext_find_entry: bad dir entry\n");
- printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
+ printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n",
dir->i_dev, dir->i_ino, offset, de->rec_len, de->name_len);
de = (struct ext_dir_entry *) (bh->b_data+BLOCK_SIZE);
offset = ((offset / BLOCK_SIZE) + 1) * BLOCK_SIZE;
de->rec_len < de->name_len + 8 ||
(((char *) de) + de->rec_len-1 >= BLOCK_SIZE+bh->b_data)) {
printk ("ext_addr_entry: bad dir entry\n");
- printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
+ printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n",
dir->i_dev, dir->i_ino, offset, de->rec_len, de->name_len);
brelse (bh);
return NULL;
if (de->rec_len < 8 || de->rec_len %4 != 0 ||
de->rec_len < de->name_len + 8) {
printk ("empty_dir: bad dir entry\n");
- printk ("dev=%d, dir=%d, offset=%d, rec_len=%d, name_len=%d\n",
+ printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n",
inode->i_dev, inode->i_ino, offset, de->rec_len, de->name_len);
brelse (bh);
return 1;
if (S_ISDIR(inode->i_mode))
goto end_unlink;
if (!inode->i_nlink) {
- printk("Deleting nonexistent file (%04x:%d), %d\n",
+ printk("Deleting nonexistent file (%04x:%ld), %d\n",
inode->i_dev,inode->i_ino,inode->i_nlink);
inode->i_nlink=1;
}
+Changes from version 0.5 to version 0.5a
+========================================
+ - New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs
+ to remove the blocks used for FS structures from the total block
+ count in statfs. With `minixdf', ext2fs mimics Minix behavior
+ in statfs (i.e. it returns the total number of blocks on the
+ partition). This is intended to make bde happy :-)
+ - New file attributes:
+ - Immutable files cannot be modified. Data cannot be written to
+ these files. They cannot be removed, renamed and new links cannot
+ be created. Even root cannot modify the files. He has to remove
+ the immutable attribute first.
+ - Append-only files: can only be written in append-mode when writing.
+ They cannot be removed, renamed and new links cannot be created.
+ Note: files may only be added to an append-only directory.
+ - No-dump files: the attribute is not used by the kernel. My port
+ of dump uses it to avoid backing up files which are not important.
+ - New check in ext2_check_dir_entry: the inode number is checked.
+ - Support for big file systems: the copy of the FS descriptor is now
+ dynamically allocated (previous versions used a fixed size array).
+ This allows to mount 2GB+ FS.
+ - Reorganization of the ext2_inode structure to allow other operating
+ systems to create specific fields if they use ext2fs as their native
+ file system. Currently, ext2fs is only implemented in Linux but
+ will soon be part of Gnu Hurd and of Masix.
+
Changes from version 0.4b to version 0.5
========================================
- New superblock fields: s_lastcheck and s_checkinterval added
{
unsigned short mode = inode->i_mode;
+ /*
+ * Nobody gets write access to an immutable file
+ */
+ if ((mask & S_IWOTH) && IS_IMMUTABLE(inode))
+ return 0;
/*
* Special case, access is always granted for root
*/
#include <asm/bitops.h>
-#define clear_block(addr,size) \
- __asm__("cld\n\t" \
- "rep\n\t" \
- "stosl" \
- : \
- :"a" (0), "c" (size / 4), "D" ((long) (addr)) \
- :"cx", "di")
-
#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
-static inline int find_first_zero_bit (unsigned long * addr, unsigned size)
-{
- int res;
-
- if (!size)
- return 0;
- __asm__("
- cld
- movl $-1,%%eax
- repe; scasl
- je 1f
- subl $4,%%edi
- movl (%%edi),%%eax
- notl %%eax
- bsfl %%eax,%%edx
- jmp 2f
-1: xorl %%edx,%%edx
-2: subl %%ebx,%%edi
- shll $3,%%edi
- addl %%edi,%%edx"
- :"=d" (res)
- :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
- :"ax", "bx", "cx", "di");
- return res;
-}
-
-static inline int find_next_zero_bit (unsigned long * addr, int size,
- int offset)
-{
- unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
- int set = 0, bit = offset & 31, res;
-
- if (bit) {
- /*
- * Look for zero in first byte
- */
- __asm__("
- bsfl %1,%0
- jne 1f
- movl $32, %0
-1: "
- : "=r" (set)
- : "r" (~(*p >> bit)));
- if (set < (32 - bit))
- return set + offset;
- set = 32 - bit;
- p++;
- }
- /*
- * No zero yet, search remaining full bytes for a zero
- */
- res = find_first_zero_bit (p, size - 32 * (p - addr));
- return (offset + set + res);
-}
-
-static inline char * find_first_zero_byte (char * addr, int size)
-{
- char *res;
-
- if (!size)
- return 0;
- __asm__("
- cld
- mov $0,%%eax
- repnz; scasb
- jnz 1f
- dec %%edi
-1: "
- : "=D" (res)
- : "0" (addr), "c" (size)
- : "ax");
- return res;
-}
-
static struct ext2_group_desc * get_group_desc (struct super_block * sb,
unsigned int block_group,
struct buffer_head ** bh)
* cyclicly search through the rest of the groups.
*/
p = ((char *) bh->b_data) + (j >> 3);
- r = find_first_zero_byte (p,
- (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
+ r = memscan(p, 0, (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
k = (r - ((char *) bh->b_data)) << 3;
if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
j = k;
}
bitmap_nr = load_block_bitmap (sb, i);
bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
- r = find_first_zero_byte (bh->b_data,
- EXT2_BLOCKS_PER_GROUP(sb) >> 3);
+ r = memscan(bh->b_data, 0, EXT2_BLOCKS_PER_GROUP(sb) >> 3);
j = (r - bh->b_data) << 3;
if (j < EXT2_BLOCKS_PER_GROUP(sb))
goto search_back;
unlock_super (sb);
return 0;
}
- clear_block (bh->b_data, sb->s_blocksize);
+ memset(bh->b_data, 0, sb->s_blocksize);
bh->b_uptodate = 1;
mark_buffer_dirty(bh, 1);
brelse (bh);
NULL, /* mmap */
NULL, /* no special open code */
NULL, /* no special release code */
- file_fsync /* fsync */
+ file_fsync, /* fsync */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL /* revalidate */
};
/*
NULL, /* follow_link */
NULL, /* bmap */
ext2_truncate, /* truncate */
- ext2_permission /* permission */
+ ext2_permission, /* permission */
+ NULL /* smap */
};
int ext2_check_dir_entry (char * function, struct inode * dir,
else if (dir && ((char *) de - bh->b_data) + de->rec_len >
dir->i_sb->s_blocksize)
error_msg = "directory entry across blocks";
+ else if (dir && de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count)
+ error_msg = "inode out of bounds";
if (error_msg != NULL)
ext2_error (dir->i_sb, function, "bad directory entry: %s\n"
generic_mmap, /* mmap */
NULL, /* no special open is needed */
ext2_release_file, /* release */
- ext2_sync_file /* fsync */
+ ext2_sync_file, /* fsync */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL /* revalidate */
};
struct inode_operations ext2_file_inode_operations = {
NULL, /* follow_link */
ext2_bmap, /* bmap */
ext2_truncate, /* truncate */
- ext2_permission /* permission */
+ ext2_permission, /* permission */
+ NULL /* smap */
};
static int ext2_file_read (struct inode * inode, struct file * filp,
#include <asm/bitops.h>
-static inline int find_first_zero_bit (unsigned long * addr, unsigned size)
-{
- int res;
-
- if (!size)
- return 0;
- __asm__("
- cld
- movl $-1,%%eax
- repe; scasl
- je 1f
- subl $4,%%edi
- movl (%%edi),%%eax
- notl %%eax
- bsfl %%eax,%%edx
- jmp 2f
-1: xorl %%edx,%%edx
-2: subl %%ebx,%%edi
- shll $3,%%edi
- addl %%edi,%%edx"
- : "=d" (res)
- : "c" ((size + 31) >> 5), "D" (addr), "b" (addr)
- : "ax", "bx", "cx", "di");
- return res;
-}
-
static struct ext2_group_desc * get_group_desc (struct super_block * sb,
unsigned int block_group,
struct buffer_head ** bh)
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;
inode->u.ext2_i.i_faddr = 0;
- inode->u.ext2_i.i_frag = 0;
- inode->u.ext2_i.i_fsize = 0;
+ inode->u.ext2_i.i_frag_no = 0;
+ inode->u.ext2_i.i_frag_size = 0;
inode->u.ext2_i.i_file_acl = 0;
inode->u.ext2_i.i_dir_acl = 0;
inode->u.ext2_i.i_dtime = 0;
#include <linux/string.h>
#include <linux/locks.h>
-#define clear_block(addr,size) \
- __asm__("cld\n\t" \
- "rep\n\t" \
- "stosl" \
- : \
- :"a" (0), "c" (size / 4), "D" ((long) (addr)) \
- :"cx", "di")
-
void ext2_put_inode (struct inode * inode)
{
ext2_discard_prealloc (inode);
"cannot get block %lu", result);
return 0;
}
- clear_block (bh->b_data, inode->i_sb->s_blocksize);
+ memset(bh->b_data, 0, inode->i_sb->s_blocksize);
bh->b_uptodate = 1;
mark_buffer_dirty(bh, 1);
brelse (bh);
inode->i_version = ++event;
inode->u.ext2_i.i_flags = raw_inode->i_flags;
inode->u.ext2_i.i_faddr = raw_inode->i_faddr;
- inode->u.ext2_i.i_frag = raw_inode->i_frag;
- inode->u.ext2_i.i_fsize = raw_inode->i_fsize;
+ inode->u.ext2_i.i_frag_no = raw_inode->i_frag;
+ inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;
inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;
inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;
inode->u.ext2_i.i_version = raw_inode->i_version;
init_fifo(inode);
if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
inode->i_flags |= MS_SYNC;
+ if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL)
+ inode->i_flags |= S_APPEND;
+ if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)
+ inode->i_flags |= S_IMMUTABLE;
}
static struct buffer_head * ext2_update_inode (struct inode * inode)
raw_inode->i_dtime = inode->u.ext2_i.i_dtime;
raw_inode->i_flags = inode->u.ext2_i.i_flags;
raw_inode->i_faddr = inode->u.ext2_i.i_faddr;
- raw_inode->i_frag = inode->u.ext2_i.i_frag;
- raw_inode->i_fsize = inode->u.ext2_i.i_fsize;
+ raw_inode->i_frag = inode->u.ext2_i.i_frag_no;
+ raw_inode->i_fsize = inode->u.ext2_i.i_frag_size;
raw_inode->i_file_acl = inode->u.ext2_i.i_file_acl;
raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;
raw_inode->i_version = inode->u.ext2_i.i_version;
unsigned long arg)
{
int err;
+ unsigned long flags;
ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);
put_fs_long (inode->u.ext2_i.i_flags, (long *) arg);
return 0;
case EXT2_IOC_SETFLAGS:
- if ((current->fsuid != inode->i_uid) && !fsuser())
- return -EPERM;
+ flags = get_fs_long ((long *) arg);
+ /*
+ * Only the super-user can change the IMMUTABLE flag
+ */
+ if (((flags & EXT2_IMMUTABLE_FL) &&
+ !(inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)) ||
+ (!(flags & EXT2_IMMUTABLE_FL) &&
+ (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL))) {
+ if (!fsuser())
+ return -EPERM;
+ } else
+ if ((current->fsuid != inode->i_uid) && !fsuser())
+ return -EPERM;
if (IS_RDONLY(inode))
return -EROFS;
- inode->u.ext2_i.i_flags = get_fs_long ((long *) arg);
+ inode->u.ext2_i.i_flags = flags;
+ if (flags & EXT2_APPEND_FL)
+ inode->i_flags |= S_APPEND;
+ else
+ inode->i_flags &= ~S_APPEND;
+ if (flags & EXT2_IMMUTABLE_FL)
+ inode->i_flags |= S_IMMUTABLE;
+ else
+ inode->i_flags &= ~S_IMMUTABLE;
inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
return 0;
static int ext2_match (int len, const char * const name,
struct ext2_dir_entry * de)
{
- unsigned char same;
-
if (!de || !de->inode || len > EXT2_NAME_LEN)
return 0;
/*
return 1;
if (len != de->name_len)
return 0;
- __asm__("cld\n\t"
- "repe ; cmpsb\n\t"
- "setz %0"
- :"=q" (same)
- :"S" ((long) name), "D" ((long) de->name), "c" (len)
- :"cx", "di", "si");
- return (int) same;
+ return !memcmp(name, de->name, len);
}
/*
retval = -EPERM;
if (S_ISDIR(inode->i_mode))
goto end_unlink;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ goto end_unlink;
if (de->inode != inode->i_ino) {
iput(inode);
brelse(bh);
iput (dir);
return -EPERM;
}
+ if (IS_APPEND(oldinode) || IS_IMMUTABLE(oldinode)) {
+ iput (oldinode);
+ iput (dir);
+ return -EPERM;
+ }
if (oldinode->i_nlink >= EXT2_LINK_MAX) {
iput (oldinode);
iput (dir);
current->fsuid != old_inode->i_uid &&
current->fsuid != old_dir->i_uid && !fsuser())
goto end_rename;
+ if (IS_APPEND(old_inode) || IS_IMMUTABLE(old_inode))
+ goto end_rename;
new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
if (new_bh) {
new_inode = __iget (new_dir->i_sb, new_de->inode, 0); /* no mntp cross */
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ext2_fs.h>
+#include <linux/malloc.h>
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/string.h>
void ext2_put_super (struct super_block * sb)
{
+ int db_count;
int i;
lock_super (sb);
mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
}
sb->s_dev = 0;
- for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
+ db_count = sb->u.ext2_sb.s_db_per_group;
+ for (i = 0; i < db_count; i++)
if (sb->u.ext2_sb.s_group_desc[i])
brelse (sb->u.ext2_sb.s_group_desc[i]);
+ kfree_s (sb->u.ext2_sb.s_group_desc,
+ db_count * sizeof (struct buffer_head *));
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
if (sb->u.ext2_sb.s_inode_bitmap[i])
brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
this_char = strtok (NULL, ",")) {
if ((value = strchr (this_char, '=')) != NULL)
*value++ = 0;
- if (!strcmp (this_char, "check")) {
+ if (!strcmp (this_char, "bsddf"))
+ clear_opt (*mount_options, MINIX_DF);
+ else if (!strcmp (this_char, "check")) {
if (!value || !*value)
set_opt (*mount_options, CHECK_NORMAL);
else if (!strcmp (value, "none")) {
else if (!strcmp (this_char, "grpid") ||
!strcmp (this_char, "bsdgroups"))
set_opt (*mount_options, GRPID);
+ else if (!strcmp (this_char, "minixdf"))
+ set_opt (*mount_options, MINIX_DF);
else if (!strcmp (this_char, "nocheck")) {
clear_opt (*mount_options, CHECK_NORMAL);
clear_opt (*mount_options, CHECK_STRICT);
unsigned long sb_block = 1;
unsigned long logic_sb_block = 1;
int dev = sb->s_dev;
- int bh_count;
+ int db_count;
int i, j;
#ifdef EXT2FS_PRE_02B_COMPAT
int fs_converted = 0;
es->s_first_data_block +
EXT2_BLOCKS_PER_GROUP(sb) - 1) /
EXT2_BLOCKS_PER_GROUP(sb);
- for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
- sb->u.ext2_sb.s_group_desc[i] = NULL;
- bh_count = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
+ db_count = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
EXT2_DESC_PER_BLOCK(sb);
- if (bh_count > EXT2_MAX_GROUP_DESC) {
+ sb->u.ext2_sb.s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
+ if (sb->u.ext2_sb.s_group_desc == NULL) {
sb->s_dev = 0;
unlock_super (sb);
brelse (bh);
- printk ("EXT2-fs: file system is too big\n");
+ printk ("EXT2-fs: not enough memory\n");
return NULL;
}
- for (i = 0; i < bh_count; i++) {
+ for (i = 0; i < db_count; i++) {
sb->u.ext2_sb.s_group_desc[i] = bread (dev, logic_sb_block + i + 1,
sb->s_blocksize);
if (!sb->u.ext2_sb.s_group_desc[i]) {
unlock_super (sb);
for (j = 0; j < i; j++)
brelse (sb->u.ext2_sb.s_group_desc[j]);
+ kfree_s (sb->u.ext2_sb.s_group_desc,
+ db_count * sizeof (struct buffer_head *));
brelse (bh);
printk ("EXT2-fs: unable to read group descriptors\n");
return NULL;
if (!ext2_check_descriptors (sb)) {
sb->s_dev = 0;
unlock_super (sb);
- for (j = 0; j < i; j++)
+ for (j = 0; j < db_count; j++)
brelse (sb->u.ext2_sb.s_group_desc[j]);
+ kfree_s (sb->u.ext2_sb.s_group_desc,
+ db_count * sizeof (struct buffer_head *));
brelse (bh);
printk ("EXT2-fs: group descriptors corrupted !\n");
return NULL;
}
sb->u.ext2_sb.s_loaded_inode_bitmaps = 0;
sb->u.ext2_sb.s_loaded_block_bitmaps = 0;
+ sb->u.ext2_sb.s_db_per_group = db_count;
unlock_super (sb);
/*
* set up enough so that it can read an inode
sb->s_op = &ext2_sops;
if (!(sb->s_mounted = iget (sb, EXT2_ROOT_INO))) {
sb->s_dev = 0;
- for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
+ for (i = 0; i < db_count; i++)
if (sb->u.ext2_sb.s_group_desc[i])
brelse (sb->u.ext2_sb.s_group_desc[i]);
+ kfree_s (sb->u.ext2_sb.s_group_desc,
+ db_count * sizeof (struct buffer_head *));
brelse (bh);
printk ("EXT2-fs: get root inode failed\n");
return NULL;
}
#ifdef EXT2FS_PRE_02B_COMPAT
if (fs_converted) {
- for (i = 0; i < bh_count; i++)
+ for (i = 0; i < db_count; i++)
mark_buffer_dirty(sb->u.ext2_sb.s_group_desc[i], 1);
sb->s_dirt = 1;
}
void ext2_statfs (struct super_block * sb, struct statfs * buf)
{
long tmp;
+ unsigned long overhead;
+ unsigned long overhead_per_group;
+
+ if (test_opt (sb, MINIX_DF))
+ overhead = 0;
+ else {
+ /*
+ * Compute the overhead (FS structures)
+ */
+ overhead_per_group = 1 /* super block */ +
+ sb->u.ext2_sb.s_db_per_group /* descriptors */ +
+ 1 /* block bitmap */ +
+ 1 /* inode bitmap */ +
+ sb->u.ext2_sb.s_itb_per_group /* inode table */;
+ overhead = sb->u.ext2_sb.s_es->s_first_data_block +
+ sb->u.ext2_sb.s_groups_count * overhead_per_group;
+ }
put_fs_long (EXT2_SUPER_MAGIC, &buf->f_type);
put_fs_long (sb->s_blocksize, &buf->f_bsize);
- put_fs_long (sb->u.ext2_sb.s_es->s_blocks_count, &buf->f_blocks);
+ put_fs_long (sb->u.ext2_sb.s_es->s_blocks_count - overhead,
+ &buf->f_blocks);
tmp = ext2_count_free_blocks (sb);
put_fs_long (tmp, &buf->f_bfree);
if (tmp >= sb->u.ext2_sb.s_es->s_r_blocks_count)
ext2_follow_link, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
- NULL /* permission */
+ NULL, /* permission */
+ NULL /* smap */
};
static int ext2_follow_link(struct inode * dir, struct inode * inode,
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/locks.h>
-
-#define clear_block(addr,size,value) \
- __asm__("cld\n\t" \
- "rep\n\t" \
- "stosl" \
- : \
- :"a" (value), "c" (size / 4), "D" ((long) (addr)) \
- :"cx", "di")
+#include <linux/string.h>
static int ext2_secrm_seed = 152; /* Random generator base */
inode->i_blocks -= blocks;
inode->i_dirt = 1;
if (inode->u.ext2_i.i_flags & EXT2_SECRM_FL) {
- clear_block (bh->b_data, inode->i_sb->s_blocksize,
- RANDOM_INT);
+ memset(bh->b_data, RANDOM_INT, inode->i_sb->s_blocksize);
mark_buffer_dirty(bh, 1);
}
brelse (bh);
*ind = 0;
mark_buffer_dirty(ind_bh, 1);
if (inode->u.ext2_i.i_flags & EXT2_SECRM_FL) {
- clear_block (bh->b_data, inode->i_sb->s_blocksize,
- RANDOM_INT);
+ memset(bh->b_data, RANDOM_INT, inode->i_sb->s_blocksize);
mark_buffer_dirty(bh, 1);
}
brelse (bh);
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ return;
ext2_discard_prealloc(inode);
while (1) {
down(&inode->i_sem);
case F_GETFL:
return filp->f_flags;
case F_SETFL:
+ /*
+ * In the case of an append-only file, O_APPEND
+ * cannot be cleared
+ */
+ if (IS_APPEND(filp->f_inode) && !(arg & O_APPEND))
+ return -EPERM;
if ((arg & FASYNC) && !(filp->f_flags & FASYNC) &&
filp->f_op->fasync)
filp->f_op->fasync(filp->f_inode, filp, 1);
static struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno,
const unsigned char *name, unsigned len,
struct quad_buffer_head *qbh);
-static struct hpfs_dirent *map_pos_dirent(struct inode *inode, off_t *posp,
+static struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
struct quad_buffer_head *qbh);
static void write_one_dirent(struct dirent *dirent, const unsigned char *name,
unsigned namelen, ino_t ino, int lowercase);
/*
* truncate count at EOF
*/
- if (count > inode->i_size - filp->f_pos)
+ if (count > inode->i_size - (off_t) filp->f_pos)
count = inode->i_size - filp->f_pos;
start = buf;
* squeeze out \r, output length varies
*/
n0 = convcpy_tofs(buf, block + r, n);
- if (count > inode->i_size - filp->f_pos - n + n0)
+ if (count > inode->i_size - (off_t) filp->f_pos - n + n0)
count = inode->i_size - filp->f_pos - n + n0;
}
lc = inode->i_sb->s_hpfs_lowercase;
- switch (filp->f_pos) {
+ switch ((off_t) filp->f_pos) {
case 0:
write_one_dirent(dirent, ".", 1, inode->i_ino, lc);
filp->f_pos = -1;
* increment *posp to point to the following dir entry.
*/
-static struct hpfs_dirent *map_pos_dirent(struct inode *inode, off_t *posp,
+static struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
struct quad_buffer_head *qbh)
{
unsigned pos, q, r;
non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
returned in bh. */
-int msdos_get_entry(struct inode *dir, off_t *pos,struct buffer_head **bh,
+int msdos_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
struct msdos_dir_entry **de)
{
int sector,offset;
static int msdos_empty(struct inode *dir)
{
- off_t pos;
+ loff_t pos;
struct buffer_head *bh;
struct msdos_dir_entry *de;
#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
+/*
+ * How long a filename can we get from user space?
+ * -EFAULT if invalid area
+ * 0 if ok (ENAMETOOLONG before EFAULT)
+ * >0 EFAULT after xx bytes
+ */
+static inline int get_max_filename(unsigned long address)
+{
+ struct vm_area_struct * vma;
+
+ if (get_fs() == KERNEL_DS)
+ return 0;
+ for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
+ if (!vma)
+ return -EFAULT;
+ if (vma->vm_end > address)
+ break;
+ }
+ if (vma->vm_start > address || !(vma->vm_page_prot & PAGE_USER))
+ return -EFAULT;
+ address = vma->vm_end - address;
+ if (address > PAGE_SIZE)
+ return 0;
+ if (vma->vm_next && vma->vm_next->vm_start == vma->vm_end &&
+ (vma->vm_next->vm_page_prot & PAGE_USER))
+ return 0;
+ return address;
+}
+
/*
* In order to reduce some races, while at the same time doing additional
* checking and hopefully speeding things up, we copy filenames to the
*/
int getname(const char * filename, char **result)
{
- int error;
- unsigned long i, page;
+ int i, error;
+ unsigned long page;
char * tmp, c;
- i = (unsigned long) filename;
- if (!i || i >= TASK_SIZE)
- return -EFAULT;
- i = TASK_SIZE - i;
+ i = get_max_filename((unsigned long) filename);
+ if (i < 0)
+ return i;
error = -EFAULT;
- if (i > PAGE_SIZE) {
- i = PAGE_SIZE;
+ if (!i) {
error = -ENAMETOOLONG;
+ i = PAGE_SIZE;
}
c = get_fs_byte(filename++);
if (!c)
*
* is used to check for read/write/execute permissions on a file.
* We use "fsuid" for this, letting us set arbitrary permissions
- * permissions for filesystem access without changing the "normal"
- * uids which are used for other things..
+ * for filesystem access without changing the "normal" uids which
+ * are used for other things..
*/
int permission(struct inode * inode,int mask)
{
if (inode->i_op && inode->i_op->permission)
return inode->i_op->permission(inode, mask);
+ else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode))
+ return 0; /* Nobody gets write access to an immutable file */
else if (current->fsuid == inode->i_uid)
mode >>= 6;
else if (in_group_p(inode->i_gid))
}
}
}
+ /*
+ * An append-only file must be opened in append mode for writing
+ */
+ if (IS_APPEND(inode) && ((flag & 2) && !(flag & O_APPEND))) {
+ iput(inode);
+ return -EPERM;
+ }
if (flag & O_TRUNC) {
inode->i_size = 0;
if (inode->i_op && inode->i_op->truncate)
iput(dir);
return -EACCES;
}
+ /*
+ * A subdirectory cannot be removed from an append-only directory
+ */
+ if (IS_APPEND(dir)) {
+ iput(dir);
+ return -EPERM;
+ }
if (!dir->i_op || !dir->i_op->rmdir) {
iput(dir);
return -EPERM;
iput(dir);
return -EACCES;
}
+ /*
+ * A file cannot be removed from an append-only directory
+ */
+ if (IS_APPEND(dir)) {
+ iput(dir);
+ return -EPERM;
+ }
if (!dir->i_op || !dir->i_op->unlink) {
iput(dir);
return -EPERM;
iput(oldinode);
return -EACCES;
}
+ /*
+ * A link to an append-only or immutable file cannot be created
+ */
+ if (IS_APPEND(oldinode) || IS_IMMUTABLE(oldinode)) {
+ iput(dir);
+ iput(oldinode);
+ return -EPERM;
+ }
if (!dir->i_op || !dir->i_op->link) {
iput(dir);
iput(oldinode);
iput(new_dir);
return -EROFS;
}
+ /*
+ * A file cannot be removed from an append-only directory
+ */
+ if (IS_APPEND(old_dir)) {
+ iput(old_dir);
+ iput(new_dir);
+ return -EPERM;
+ }
if (!old_dir->i_op || !old_dir->i_op->rename) {
iput(old_dir);
iput(new_dir);
iput(inode);
return -EROFS;
}
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+ iput(inode);
+ return -EPERM;
+ }
inode->i_size = length;
if (inode->i_op && inode->i_op->truncate)
inode->i_op->truncate(inode);
return -ENOENT;
if (S_ISDIR(inode->i_mode) || !(file->f_mode & 2))
return -EACCES;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ return -EPERM;
inode->i_size = length;
if (inode->i_op && inode->i_op->truncate)
inode->i_op->truncate(inode);
{
struct inode * inode;
struct file * file;
+ uid_t old_user;
+ gid_t old_group;
+ int notify_flag = 0;
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
return -ENOENT;
if (IS_RDONLY(inode))
return -EROFS;
+ old_user = inode->i_uid;
+ old_group = inode->i_gid;
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
fsuser()) {
inode->i_uid = user;
inode->i_gid = group;
+ /*
+ * If the owner has been changed, remove the setuid bit
+ */
+ if (old_user != inode->i_uid && inode->i_mode & S_ISUID) {
+ inode->i_mode &= ~S_ISUID;
+ notify_flag = NOTIFY_MODE;
+ }
+ /*
+ * If the group has been changed, remove the setgid bit
+ */
+ if (old_group != inode->i_gid && inode->i_mode & S_ISGID) {
+ inode->i_mode &= ~S_ISGID;
+ notify_flag = NOTIFY_MODE;
+ }
inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
- return notify_change(NOTIFY_UIDGID, inode);
+ return notify_change(notify_flag | NOTIFY_UIDGID, inode);
}
return -EPERM;
}
{
struct inode * inode;
int error;
+ uid_t old_user;
+ gid_t old_group;
+ int notify_flag = 0;
error = lnamei(filename,&inode);
if (error)
iput(inode);
return -EROFS;
}
+ old_user = inode->i_uid;
+ old_group = inode->i_uid;
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
fsuser()) {
inode->i_uid = user;
inode->i_gid = group;
+ /*
+ * If the owner has been changed, remove the setuid bit
+ */
+ if (old_user != inode->i_uid && inode->i_mode & S_ISUID) {
+ inode->i_mode &= ~S_ISUID;
+ notify_flag = NOTIFY_MODE;
+ }
+ /*
+ * If the group has been changed, remove the setgid bit
+ */
+ if (old_group != inode->i_gid && inode->i_mode & S_ISGID) {
+ inode->i_mode &= ~S_ISGID;
+ notify_flag = NOTIFY_MODE;
+ }
inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
- error = notify_change(NOTIFY_UIDGID, inode);
+ error = notify_change(notify_flag | NOTIFY_UIDGID, inode);
iput(inode);
return error;
}
return file->f_pos;
}
+asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
+ unsigned long offset_low, loff_t * result,
+ unsigned int origin)
+{
+ struct file * file;
+ loff_t tmp = -1;
+ loff_t offset;
+ int err;
+
+ if (fd >= NR_OPEN || !(file=current->files->fd[fd]) || !(file->f_inode))
+ return -EBADF;
+ if (origin > 2)
+ return -EINVAL;
+ if ((err = verify_area(VERIFY_WRITE, result, sizeof(loff_t))))
+ return err;
+ offset = (loff_t) (((unsigned long long) offset_high << 32) | offset_low);
+/* there is no fs specific llseek handler */
+ switch (origin) {
+ case 0:
+ tmp = offset;
+ break;
+ case 1:
+ tmp = file->f_pos + offset;
+ break;
+ case 2:
+ if (!file->f_inode)
+ return -EINVAL;
+ tmp = file->f_inode->i_size + offset;
+ break;
+ }
+ if (tmp < 0)
+ return -EINVAL;
+ file->f_pos = tmp;
+ file->f_reada = 0;
+ memcpy_tofs(result, &file->f_pos, sizeof(loff_t));
+ return 0;
+}
+
asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
{
int error;
int error;
struct file * file;
struct inode * inode;
+ int written;
if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
return -EBADF;
error = verify_area(VERIFY_READ,buf,count);
if (error)
return error;
- return file->f_op->write(inode,file,buf,count);
+ written = file->f_op->write(inode,file,buf,count);
+ /*
+ * If data has been written to the file, remove the setuid and
+ * the setgid bits
+ */
+ if (written > 0 && !suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
+ inode->i_mode &= ~(S_ISUID | S_ISGID);
+ notify_change (NOTIFY_MODE, inode);
+ }
+ return written;
}
if (i) {
if (de->inode > inode->i_sb->sv_ninodes)
printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n",
- inode->i_dev, inode->i_ino, filp->f_pos - SYSV_DIRSIZE, de->inode);
+ inode->i_dev, inode->i_ino, (off_t) filp->f_pos - SYSV_DIRSIZE, de->inode);
put_fs_long(de->inode,&dirent->d_ino);
put_fs_byte(0,i+dirent->d_name);
put_fs_word(i,&dirent->d_reclen);
return oldbit;
}
+/*
+ * Find-bit routines..
+ */
+extern inline int find_first_zero_bit (unsigned long * addr, unsigned size)
+{
+ int res;
+
+ if (!size)
+ return 0;
+ __asm__("
+ cld
+ movl $-1,%%eax
+ repe; scasl
+ je 1f
+ subl $4,%%edi
+ movl (%%edi),%%eax
+ notl %%eax
+ bsfl %%eax,%%edx
+ jmp 2f
+1: xorl %%edx,%%edx
+2: subl %%ebx,%%edi
+ shll $3,%%edi
+ addl %%edi,%%edx"
+ :"=d" (res)
+ :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
+ :"ax", "bx", "cx", "di");
+ return res;
+}
+
+extern inline int find_next_zero_bit (unsigned long * addr, int size,
+ int offset)
+{
+ unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+ int set = 0, bit = offset & 31, res;
+
+ if (bit) {
+ /*
+ * Look for zero in first byte
+ */
+ __asm__("
+ bsfl %1,%0
+ jne 1f
+ movl $32, %0
+1: "
+ : "=r" (set)
+ : "r" (~(*p >> bit)));
+ if (set < (32 - bit))
+ return set + offset;
+ set = 32 - bit;
+ p++;
+ }
+ /*
+ * No zero yet, search remaining full bytes for a zero
+ */
+ res = find_first_zero_bit (p, size - 32 * (p - addr));
+ return (offset + set + res);
+}
+
#endif /* _I386_BITOPS_H */
#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
-#define outb outb_p
+#define dma_outb outb_p
+#else
+#define dma_outb outb
#endif
/*
static __inline__ void enable_dma(unsigned int dmanr)
{
if (dmanr<=3)
- outb(dmanr, DMA1_MASK_REG);
+ dma_outb(dmanr, DMA1_MASK_REG);
else
- outb(dmanr & 3, DMA2_MASK_REG);
+ dma_outb(dmanr & 3, DMA2_MASK_REG);
}
static __inline__ void disable_dma(unsigned int dmanr)
{
if (dmanr<=3)
- outb(dmanr | 4, DMA1_MASK_REG);
+ dma_outb(dmanr | 4, DMA1_MASK_REG);
else
- outb((dmanr & 3) | 4, DMA2_MASK_REG);
+ dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
}
/* Clear the 'DMA Pointer Flip Flop'.
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
if (dmanr<=3)
- outb(0, DMA1_CLEAR_FF_REG);
+ dma_outb(0, DMA1_CLEAR_FF_REG);
else
- outb(0, DMA2_CLEAR_FF_REG);
+ dma_outb(0, DMA2_CLEAR_FF_REG);
}
/* set mode (above) for a specific DMA channel */
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
if (dmanr<=3)
- outb(mode | dmanr, DMA1_MODE_REG);
+ dma_outb(mode | dmanr, DMA1_MODE_REG);
else
- outb(mode | (dmanr&3), DMA2_MODE_REG);
+ dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
}
/* Set only the page register bits of the transfer address.
{
switch(dmanr) {
case 0:
- outb(pagenr, DMA_PAGE_0);
+ dma_outb(pagenr, DMA_PAGE_0);
break;
case 1:
- outb(pagenr, DMA_PAGE_1);
+ dma_outb(pagenr, DMA_PAGE_1);
break;
case 2:
- outb(pagenr, DMA_PAGE_2);
+ dma_outb(pagenr, DMA_PAGE_2);
break;
case 3:
- outb(pagenr, DMA_PAGE_3);
+ dma_outb(pagenr, DMA_PAGE_3);
break;
case 5:
- outb(pagenr & 0xfe, DMA_PAGE_5);
+ dma_outb(pagenr & 0xfe, DMA_PAGE_5);
break;
case 6:
- outb(pagenr & 0xfe, DMA_PAGE_6);
+ dma_outb(pagenr & 0xfe, DMA_PAGE_6);
break;
case 7:
- outb(pagenr & 0xfe, DMA_PAGE_7);
+ dma_outb(pagenr & 0xfe, DMA_PAGE_7);
break;
}
}
{
set_dma_page(dmanr, a>>16);
if (dmanr <= 3) {
- outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
} else {
- outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
}
}
{
count--;
if (dmanr <= 3) {
- outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
} else {
- outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
}
}
return __res;
}
-extern inline void * memset(void * s,char c,size_t count)
+extern inline void * __memset_generic(void * s,char c,size_t count)
{
__asm__ __volatile__(
"cld\n\t"
return s;
}
+/* we might want to write optimized versions of these later */
+#define __constant_c_memset(s,c,count) __memset_generic((s),(c),(count))
+#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as we by now know that both pattern and count is constant..
+ */
+extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+{
+ switch (count) {
+ case 0:
+ return s;
+ case 1:
+ *(unsigned char *)s = pattern;
+ return s;
+ case 2:
+ *(unsigned short *)s = pattern;
+ return s;
+ case 3:
+ *(unsigned short *)s = pattern;
+ *(2+(unsigned char *)s) = pattern >> 16;
+ return s;
+ case 4:
+ *(unsigned long *)s = pattern;
+ return s;
+ }
+#define COMMON(x) \
+__asm__("cld\n\t" \
+ "rep ; stosl" \
+ x \
+ : /* no outputs */ \
+ : "a" (pattern),"c" (count/4),"D" ((long) s) \
+ : "cx","di","memory")
+
+ switch (count % 4) {
+ case 0: COMMON(""); return s;
+ case 1: COMMON("\n\tstosb"); return s;
+ case 2: COMMON("\n\tstosw"); return s;
+ case 3: COMMON("\n\tstosw\n\tstosb"); return s;
+ }
+#undef COMMON
+}
+
+#define __constant_c_x_memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_c_and_count_memset((s),(c),(count)) : \
+ __constant_c_memset((s),(c),(count)))
+
+#define __memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_count_memset((s),(c),(count)) : \
+ __memset_generic((s),(c),(count)))
+
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? \
+ __constant_c_x_memset((s),(0x01010101*(unsigned char)c),(count)) : \
+ __memset((s),(c),(count)))
+
+/*
+ * find the first occurrence of byte 'c', or 1 past the area if none
+ */
+extern inline char * memscan(void * addr, unsigned char c, int size)
+{
+ if (!size)
+ return addr;
+ __asm__("cld
+ repnz; scasb
+ jnz 1f
+ dec %%edi
+1: "
+ : "=D" (addr), "=c" (size)
+ : "0" (addr), "1" (size), "a" (c));
+ return addr;
+}
+
#endif
#define _ASM_MIPS_MIPSREGS_H_
/*
- * The following macros are espacially usefull for __asm__
+ * The following macros are especially useful for __asm__
* inline assembler.
*/
#endif
/*
- * Coprozessor 0 register names
+ * Coprocessor 0 register names
*/
#define CP0_INDEX $0
#define CP0_RANDOM $1
/*
* The second extended file system version
*/
-#define EXT2FS_DATE "94/03/10"
-#define EXT2FS_VERSION "0.5"
+#define EXT2FS_DATE "94/08/12"
+#define EXT2FS_VERSION "0.5a"
/*
* Debug code
/*
* Inode flags
*/
-#define EXT2_SECRM_FL 0x0001 /* Secure deletion */
-#define EXT2_UNRM_FL 0x0002 /* Undelete */
-#define EXT2_COMPR_FL 0x0004 /* Compress file */
-#define EXT2_SYNC_FL 0x0008 /* Synchronous updates */
+#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
+#define EXT2_UNRM_FL 0x00000002 /* Undelete */
+#define EXT2_COMPR_FL 0x00000004 /* Compress file */
+#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
/*
* ioctl commands
unsigned short i_links_count; /* Links count */
unsigned long i_blocks; /* Blocks count */
unsigned long i_flags; /* File flags */
- unsigned long i_reserved1;
+ union {
+ struct {
+ unsigned long l_i_reserved1;
+ } linux1;
+ struct {
+ unsigned long h_i_translator;
+ } hurd1;
+ struct {
+ unsigned long m_i_reserved1;
+ } masix1;
+ } osd1; /* OS dependent 1 */
unsigned long i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
unsigned long i_version; /* File version (for NFS) */
unsigned long i_file_acl; /* File ACL */
unsigned long i_dir_acl; /* Directory ACL */
unsigned long i_faddr; /* Fragment address */
- unsigned char i_frag; /* Fragment number */
- unsigned char i_fsize; /* Fragment size */
- unsigned short i_pad1;
- unsigned long i_reserved2[2];
+ union {
+ struct {
+ unsigned char l_i_frag; /* Fragment number */
+ unsigned char l_i_fsize; /* Fragment size */
+ unsigned short i_pad1;
+ unsigned long l_i_reserved2[2];
+ } linux2;
+ struct {
+ unsigned char h_i_frag; /* Fragment number */
+ unsigned char h_i_fsize; /* Fragment size */
+ unsigned short h_i_mode_high;
+ unsigned short h_i_uid_high;
+ unsigned short h_i_gid_high;
+ unsigned long h_i_author;
+ } hurd2;
+ struct {
+ unsigned char m_i_frag; /* Fragment number */
+ unsigned char m_i_fsize; /* Fragment size */
+ unsigned short m_pad1;
+ unsigned long m_i_reserved2[2];
+ } masix2;
+ } osd2; /* OS dependent 2 */
};
+#ifdef __linux__
+#define i_reserved1 osd1.linux1.l_i_reserved1
+#define i_frag osd2.linux2.l_i_frag
+#define i_fsize osd2.linux2.l_i_fsize
+#define i_reserved2 osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef __hurd__
+#define i_translator osd1.hurd1.h_i_translator
+#define i_frag osd2.hurd2.h_i_frag;
+#define i_fsize osd2.hurd2.h_i_fsize;
+#define i_uid_high osd2.hurd2.h_i_uid_high
+#define i_gid_high osd2.hurd2.h_i_gid_high
+#define i_author osd2.hurd2.h_i_author
+#endif
+
+#ifdef __masix__
+#define i_reserved1 osd1.masix1.m_i_reserved1
+#define i_frag osd2.masix2.m_i_frag
+#define i_fsize osd2.masix2.m_i_fsize
+#define i_reserved2 osd2.masix2.m_i_reserved2
+#endif
+
/*
* File system states
*/
#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
unsigned short s_pad;
unsigned long s_lastcheck; /* time of last check */
unsigned long s_checkinterval; /* max. time between checks */
- unsigned long s_reserved[238]; /* Padding to the end of the block */
+ unsigned long s_creator_os; /* OS */
+ unsigned long s_reserved[237]; /* Padding to the end of the block */
};
+#define EXT2_OS_LINUX 0
+#define EXT2_OS_HURD 1
+#define EXT2_OS_MASIX 2
+
/*
* Structure of a directory entry
*/
unsigned long);
/* namei.c */
-extern int ext2_open (struct inode *, struct file *);
extern void ext2_release (struct inode *, struct file *);
extern int ext2_lookup (struct inode *,const char *, int, struct inode **);
extern int ext2_create (struct inode *,const char *, int, int,
unsigned long i_data[15];
unsigned long i_flags;
unsigned long i_faddr;
- unsigned char i_frag;
- unsigned char i_fsize;
+ unsigned char i_frag_no;
+ unsigned char i_frag_size;
unsigned short i_pad1;
unsigned long i_file_acl;
unsigned long i_dir_acl;
#ifndef _LINUX_EXT2_FS_SB
#define _LINUX_EXT2_FS_SB
-#define EXT2_MAX_GROUP_DESC 8
+/*
+ * The following is not needed anymore since the descriptors buffer
+ * heads are now dynamically allocated
+ */
+/* #define EXT2_MAX_GROUP_DESC 8 */
+
#define EXT2_MAX_GROUP_LOADED 8
/*
unsigned long s_blocks_per_group;/* Number of blocks in a group */
unsigned long s_inodes_per_group;/* Number of inodes in a group */
unsigned long s_itb_per_group; /* Number of inode table blocks per group */
+ unsigned long s_db_per_group; /* Number of descriptor blocks per group */
unsigned long s_desc_per_block; /* Number of group descriptors per block */
unsigned long s_groups_count; /* Number of groups in the fs */
struct buffer_head * s_sbh; /* Buffer containing the super block */
struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */
- struct buffer_head * s_group_desc[EXT2_MAX_GROUP_DESC];
+ struct buffer_head ** s_group_desc;
unsigned short s_loaded_inode_bitmaps;
unsigned short s_loaded_block_bitmaps;
unsigned long s_inode_bitmap_number[EXT2_MAX_GROUP_LOADED];
#define MS_SYNC 16 /* writes are synced at once */
#define MS_REMOUNT 32 /* alter flags of a mounted FS */
+#define S_APPEND 256 /* append-only file */
+#define S_IMMUTABLE 512 /* immutable file */
+
/*
* Flags that can be altered by MS_REMOUNT
*/
#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
#define IS_SYNC(inode) ((inode)->i_flags & MS_SYNC)
+#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
+#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
+
/* the read-only stuff doesn't really belong here, but any other place is
probably as bad and I don't want to create yet another include file. */
struct file {
mode_t f_mode;
- off_t f_pos;
+ loff_t f_pos;
unsigned short f_flags;
unsigned short f_count;
off_t f_reada;
extern int date_dos2unix(unsigned short time,unsigned short date);
extern void date_unix2dos(int unix_date,unsigned short *time,
unsigned short *date);
-extern int msdos_get_entry(struct inode *dir,off_t *pos,struct buffer_head **bh,
+extern int msdos_get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh,
struct msdos_dir_entry **de);
extern int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh,
struct msdos_dir_entry **res_de,int *ino);
extern int pcibios_present (void);
-#define PCIBIOS_SUCCESFUL 0x00
+#define PCIBIOS_SUCCESSFUL 0x00
#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
#define PCIBIOS_BAD_VENDOR_ID 0x83
#define PCIBIOS_DEVICE_NOT_FOUND 0x86
struct vm_area_struct * mmap;
};
+#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, }
+
#define INIT_MM { \
0, \
0, 0, 0, \
/* ?_flt */ 0, 0, 0, 0, \
0, \
/* swap */ 0, 0, 0, 0, \
- NULL }
+ &init_mmap }
struct task_struct {
/* these are hardcoded - don't touch */
* hannu@voxware.pp.fi
*/
-#define SOUND_VERSION 203
+#define SOUND_VERSION 300
#define VOXWARE
#include <sys/ioctl.h>
#ifndef _LINUX_TQUEUE_H
#define _LINUX_TQUEUE_H
+#include <asm/bitops.h>
+#include <asm/system.h>
+
#ifdef INCLUDE_INLINE_FUNCS
#define _INLINE_ extern
#else
_INLINE_ void queue_task_irq(struct tq_struct *bh_pointer,
task_queue *bh_list)
{
- int l1;
-
- __asm__ __volatile__ (
- "btsl $0,%1\n\t" /* bottom half already marked? */
- "jc 1f\n\t"
- "leal %2,%3\n\t" /* address of the "next" field of bh_struct */
- "xchgl %3,%0\n\t" /* link bottom half into list */
- "movl %3,%2\n1:" /* save the pointer to next bottom half */
- : "=m" (*bh_list), "=m" (bh_pointer -> sync), "=m" (bh_pointer -> next),
- "=r" (l1) );
+ if (!set_bit(0,&bh_pointer->sync)) {
+ bh_pointer->next = *bh_list;
+ *bh_list = bh_pointer;
+ }
}
/*
_INLINE_ void queue_task_irq_off(struct tq_struct *bh_pointer,
task_queue *bh_list)
{
- int l1;
-
- __asm__ __volatile__ (
- "testl $1,%1\n\t" /* bottom half already marked? */
- "jne 1f\n\t"
- "movl $1,%1\n\t"
- "leal %2,%3\n\t" /* address of the "next" field of bh_struct */
- "xchgl %3,%0\n\t" /* link bottom half into list */
- "movl %3,%2\n1:" /* save the pointer to next bottom half */
- : "=m" (*bh_list), "=m" (bh_pointer -> sync), "=m" (bh_pointer -> next),
- "=r" (l1) );
+ if (!(bh_pointer->sync & 1)) {
+ bh_pointer->sync = 1;
+ bh_pointer->next = *bh_list;
+ *bh_list = bh_pointer;
+ }
}
_INLINE_ void queue_task(struct tq_struct *bh_pointer,
task_queue *bh_list)
{
- int l1;
-
- __asm__ __volatile__ (
- "btsl $0,%1\n\t"
- "jc 1f\n\t"
- "leal %2,%3\n\t"
- "pushfl\n\t" /* save interrupt flag */
- "cli\n\t" /* turn off interrupts */
- "xchgl %3,%0\n\t"
- "movl %3,%2\n\t" /* now the linking step is really atomic! */
- "popfl\n1:" /* restore interrupt flag */
- : "=m" (*bh_list), "=m" (bh_pointer -> sync), "=m" (bh_pointer -> next),
- "=r" (l1) );
+ if (!set_bit(0,&bh_pointer->sync)) {
+ unsigned long flags;
+ save_flags(flags);
+ cli();
+ bh_pointer->next = *bh_list;
+ *bh_list = bh_pointer;
+ restore_flags(flags);
+ }
}
/*
typedef unsigned short nlink_t;
typedef int daddr_t;
typedef long off_t;
+#define _LOFF_T
+typedef long long loff_t;
/* bsd */
typedef unsigned char u_char;
#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
#define __NR_setfsuid 138
#define __NR_setfsgid 139
+#define __NR__llseek 140
extern int errno;
static char buf[80];
switch (error) {
- case PCIBIOS_SUCCESFUL:
- return "SUCCESFUL";
+ case PCIBIOS_SUCCESSFUL:
+ return "SUCCESSFUL";
case PCIBIOS_FUNC_NOT_SUPPORTED:
return "FUNC_NOT_SUPPORTED";
X(dev_rint),
X(dev_tint),
X(irq2dev_map),
- X(dev_kfree_skb),
#endif
/********************************************************
asmlinkage int system_call(void);
static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, };
+static struct vm_area_struct init_mmap = INIT_MMAP;
struct task_struct init_task = INIT_TASK;
unsigned long volatile jiffies=0;
/*
* "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
- * is used for "access()" and for the NFS deamon (letting nfsd stay at
+ * is used for "access()" and for the NFS daemon (letting nfsd stay at
* whatever uid it wants to). It normally shadows "euid", except when
* explicitly set by setfsuid() or for access..
*/
.long 0 /* for afs_syscall */
.long _sys_setfsuid
.long _sys_setfsgid
-
- .space (NR_syscalls-137)*4
+ .long _sys_llseek /* 140 */
+ .space (NR_syscalls-139)*4
+ .space (NR_syscalls-140)*4
}
read_swap_page(entry, (char *) page);
if (add_to_swap_cache(page, entry))
- return page | PAGE_PRIVATE;
+ return page | PAGE_PRESENT;
swap_free(entry);
- return page | PAGE_DIRTY | PAGE_PRIVATE;
+ return page | PAGE_DIRTY | PAGE_PRESENT;
}
static inline int try_to_swap_out(unsigned long * table_ptr)
o MTU recognized in routing table (but only by TCP currently)
o AX.25 PI driver merged into AX.25 code and kernel stubs
o UNIX /proc trap hopefully fixed
-o DDI removed totally ready to use the PCMICA people's stuff
+o DDI removed totally ready to use the PCMCIA people's stuff
o Unix domain lock/unlock now static (needlessly visible before)
o Split net/inet/sock.c into generic and IP components
o NFS client works correctly with 8K NFS
o Johnathon Naylor(G4KLX) AX.25 changes
o Out of sync bug in lance driver fixed.
o First cut at ethernet loadable modules
-o PCMICA people have ifmap stuff. Will extend this to other drivers.
+o PCMCIA people have ifmap stuff. Will extend this to other drivers.
o New de600.c
o Clean up of IP layer - sorted a lot of redundant and duplicated code
out.
IS_SKB(skb);
kfree_skb(skb, FREE_WRITE);
}
+
+ /*
+ * Don't discard received data until the user side kills its
+ * half of the socket.
+ */
- while((skb=skb_dequeue(&sk->receive_queue))!=NULL) {
- /*
- * This will take care of closing sockets that were
- * listening and didn't accept everything.
- */
- if (skb->sk != NULL && skb->sk != sk)
- {
+ if (sk->dead)
+ {
+ while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
+ {
+ /*
+ * This will take care of closing sockets that were
+ * listening and didn't accept everything.
+ */
+ if (skb->sk != NULL && skb->sk != sk)
+ {
+ IS_SKB(skb);
+ skb->sk->dead = 1;
+ skb->sk->prot->close(skb->sk, 0);
+ }
IS_SKB(skb);
- skb->sk->dead = 1;
- skb->sk->prot->close(skb->sk, 0);
+ kfree_skb(skb, FREE_READ);
}
- IS_SKB(skb);
- kfree_skb(skb, FREE_READ);
- }
+ }
/* Now we need to clean up the send head. */
cli();
* Ross Martin : Rewrote arp_rcv() and arp_get_info()
* Stephen Henson : Add AX25 support to arp_get_info()
* Alan Cox : Drop data when a device is downed.
- * Alan Cox : Use init_timer()
+ * Alan Cox : Use init_timer().
+ * Alan Cox : Double lock fixes.
*/
#include <linux/types.h>
*/
if (skb != NULL)
+ {
skb_queue_tail(&entry->skb, skb);
+ skb_device_unlock(skb);
+ }
sti();
return 1;
}
entry->retries = ARP_MAX_TRIES;
skb_queue_head_init(&entry->skb);
if (skb != NULL)
+ {
skb_queue_tail(&entry->skb, skb);
+ skb_device_unlock(skb);
+ }
}
else
{
* Alan Cox : device private ioctl copies fields back.
* Alan Cox : Transmit queue code does relevant stunts to
* keep the queue safe.
+ * Alan Cox : Fixed double lock.
*
* Cleaned up and recommented by Alan Cox 2nd April 1994. I hope to have
* the rest as well commented in the end.
*/
if (!skb->arp && dev->rebuild_header(skb->data, dev, skb->raddr, skb)) {
- skb_device_unlock(skb); /* It's now safely on the arp queue */
return;
}
* unhooks any devices that fail to initialise (normally hardware not
* present) and leaves us with a valid list of present and active devices.
*
- * The PCMICA code may need to change this a little, and add a pair
+ * The PCMCIA code may need to change this a little, and add a pair
* of register_inet_device() unregister_inet_device() calls. This will be
* needed for ethernet as modules support.
*/
* (Support old BSD in other words). This old BSD
* support will go very soon as it messes other things
* up.
+ * Also accept `loopback broadcast' as BROADCAST.
*/
- if (addr == INADDR_ANY || addr == INADDR_BROADCAST)
+ if (addr == INADDR_ANY || addr == INADDR_BROADCAST ||
+ addr == htonl(0x7FFFFFFFL))
return IS_BROADCAST;
mask = ip_get_mask(addr);
* Alan Cox : Always defrag, moved IP_FORWARD to the config.in file
* Alan Cox : IP options adjust sk->priority.
* Pedro Roque : Fix mtu/length error in ip_forward.
+ * Alan Cox : Avoid ip_chk_addr when possible.
*
* To Fix:
* IP option processing is mostly not needed. ip_forward needs to know about routing rules
struct inet_protocol *ipprot;
static struct options opt; /* since we don't use these yet, and they
take up stack space. */
- int brd;
+ int brd=IS_MYADDR;
int is_frag=0;
* This is inefficient. While finding out if it is for us we could also compute
* the routing table entry. This is where the great unified cache theory comes
* in as and when someone implements it
+ *
+ * For most hosts over 99% of packets match the first conditional
+ * and don't go via ip_chk_addr. Note: brd is set to IS_MYADDR at
+ * function entry.
*/
- if ((brd = ip_chk_addr(iph->daddr)) == 0)
+ if ( iph->daddr != skb->dev->pa_addr && (brd = ip_chk_addr(iph->daddr)) == 0)
{
/*
* Don't forward multicast or broadcast frames.
* Alan Cox : TCP fast path debugging
* Alan Cox : Window clamping
* Michael Riepe : Bug in tcp_check()
+ * Matt Dillon : More TCP improvements and RST bug fixes
*
*
* To Fix:
return(b);
}
+#undef STATE_TRACE
+
+static __inline__ void tcp_set_state(struct sock *sk, int state)
+{
+ if(sk->state==TCP_ESTABLISHED)
+ tcp_statistics.TcpCurrEstab--;
+#ifdef STATE_TRACE
+ if(sk->debug)
+ printk("TCP sk=%s, State %d -> %d\n",sk, sk->state,state);
+#endif
+ sk->state=state;
+ if(state==TCP_ESTABLISHED)
+ tcp_statistics.TcpCurrEstab++;
+}
/* This routine picks a TCP windows for a socket based on
the following constraints
static void tcp_time_wait(struct sock *sk)
{
- sk->state = TCP_TIME_WAIT;
+ tcp_set_state(sk,TCP_TIME_WAIT);
sk->shutdown = SHUTDOWN_MASK;
if (!sk->dead)
sk->state_change(sk);
if (sk->state == TCP_SYN_SENT)
{
tcp_statistics.TcpAttemptFails++;
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->error_report(sk); /* Wake people up to see the error (see connect in sock.c) */
}
sk->err = icmp_err_convert[err & 0xff].errno;
prot->wfree(sk,buff->mem_addr, buff->mem_len);
if (sk->state == TCP_ESTABLISHED)
- sk->state = TCP_FIN_WAIT1;
+ tcp_set_state(sk,TCP_FIN_WAIT1);
else if(sk->state == TCP_CLOSE_WAIT)
- sk->state = TCP_LAST_ACK;
+ tcp_set_state(sk,TCP_LAST_ACK);
else
- sk->state = TCP_FIN_WAIT2;
+ tcp_set_state(sk,TCP_FIN_WAIT2);
release_sock(sk);
return;
}
if (sk->state == TCP_ESTABLISHED)
- sk->state = TCP_FIN_WAIT1;
+ tcp_set_state(sk,TCP_FIN_WAIT1);
else if (sk->state == TCP_CLOSE_WAIT)
- sk->state = TCP_LAST_ACK;
+ tcp_set_state(sk,TCP_LAST_ACK);
else
- sk->state = TCP_FIN_WAIT2;
+ tcp_set_state(sk,TCP_FIN_WAIT2);
release_sock(sk);
}
if (!sk->dead)
sk->state_change(sk);
- /*
- * We need to flush the recv. buffs.
- */
-
- if (skb_peek(&sk->receive_queue) != NULL)
+ if (timeout == 0)
{
- struct sk_buff *skb;
- if(sk->debug)
- printk("Clean rcv queue\n");
- while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
+ /*
+ * We need to flush the recv. buffs. We do this only on the
+ * descriptor close, not protocol-sourced closes, because the
+ * reader process may not have drained the data yet!
+ */
+
+ if (skb_peek(&sk->receive_queue) != NULL)
{
- /* The +1 is not needed because the FIN takes up sequence space and
- is not read!!! */
- if(skb->len > 0 && after(skb->h.th->seq + skb->len/* + 1 */ , sk->copied_seq))
- need_reset = 1;
- kfree_skb(skb, FREE_READ);
+ struct sk_buff *skb;
+ if(sk->debug)
+ printk("Clean rcv queue\n");
+ while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
+ {
+ /* The +1 is not needed because the FIN takes up seq
+ is not read!!! */
+ if(skb->len > 0 && after(skb->h.th->seq + skb->len , sk->copied_seq))
+ need_reset = 1;
+ kfree_skb(skb, FREE_READ);
+ }
+ if(sk->debug)
+ printk("Cleaned.\n");
}
- if(sk->debug)
- printk("Cleaned.\n");
}
/*
*/
if (timeout)
{
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
}
release_sock(sk);
return;
case TCP_LISTEN:
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
release_sock(sk);
return;
case TCP_CLOSE:
first. Anyway it might work now */
release_sock(sk);
if (sk->state != TCP_CLOSE_WAIT)
- sk->state = TCP_ESTABLISHED;
+ tcp_set_state(sk,TCP_ESTABLISHED);
reset_timer(sk, TIME_CLOSE, 100);
return;
}
*/
if(sk->state==TCP_ESTABLISHED)
- sk->state=TCP_FIN_WAIT1;
+ tcp_set_state(sk,TCP_FIN_WAIT1);
else
- sk->state=TCP_FIN_WAIT2;
+ tcp_set_state(sk,TCP_FIN_WAIT2);
reset_timer(sk, TIME_CLOSE,4*sk->rto);
if(timeout)
tcp_time_wait(sk);
*/
if (sk->state == TCP_ESTABLISHED)
- sk->state = TCP_FIN_WAIT1;
+ tcp_set_state(sk,TCP_FIN_WAIT1);
else if (sk->state == TCP_CLOSE_WAIT)
- sk->state = TCP_LAST_ACK;
+ tcp_set_state(sk,TCP_LAST_ACK);
else if (sk->state != TCP_CLOSING)
- sk->state = TCP_FIN_WAIT2;
+ tcp_set_state(sk,TCP_FIN_WAIT2);
}
release_sock(sk);
}
{
if(sk->debug)
printk("Ack ignored %lu %lu\n",ack,sk->sent_seq);
+
/*
- * What is all this crap? the ack sequence number is bad or
- * old, we should return 0 to ignore the packet. XXX
+ * Keepalive processing.
*/
- return(0);
-#ifdef NOTDEF
- if (after(ack, sk->sent_seq) ||
- (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT))
+
+ if (after(ack, sk->sent_seq) || (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT))
{
return(0);
}
if (sk->keepopen)
{
- reset_timer(sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
+ if(sk->timeout==TIME_KEEPOPEN)
+ reset_timer(sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
}
return(1);
-#endif
}
if (len != th->doff*4)
if (sk->rcv_ack_seq == sk->write_seq && sk->acked_seq == sk->fin_seq)
{
flag |= 1;
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->shutdown = SHUTDOWN_MASK;
}
}
else
{
sk->shutdown = SHUTDOWN_MASK;
- sk->state = TCP_FIN_WAIT2;
+ tcp_set_state(sk,TCP_FIN_WAIT2);
}
}
}
tcp_reset(sk->saddr, sk->daddr, skb->h.th,
sk->prot, NULL, skb->dev, sk->ip_tos, sk->ip_ttl);
tcp_statistics.TcpEstabResets++;
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->err = EPIPE;
sk->shutdown = SHUTDOWN_MASK;
kfree_skb(skb, FREE_READ);
*/
reset_timer(sk, TIME_CLOSE, TCP_TIMEOUT_LEN);
/*sk->fin_seq = th->seq+1;*/
- tcp_statistics.TcpCurrEstab--;
- sk->state = TCP_CLOSE_WAIT;
+ tcp_set_state(sk,TCP_CLOSE_WAIT);
if (th->rst)
sk->shutdown = SHUTDOWN_MASK;
break;
* XXX timeout not set properly
*/
- tcp_statistics.TcpCurrEstab--;
reset_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
/*sk->fin_seq = th->seq+1;*/
- sk->state = TCP_CLOSING;
+ tcp_set_state(sk,TCP_CLOSING);
break;
case TCP_FIN_WAIT2:
/*
*/
reset_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
/*sk->fin_seq = th->seq+1;*/
- sk->state = TCP_TIME_WAIT;
+ tcp_set_state(sk,TCP_TIME_WAIT);
break;
case TCP_CLOSE:
/*
*/
break;
default:
- sk->state = TCP_LAST_ACK;
+ tcp_set_state(sk,TCP_LAST_ACK);
/* Start the timers. */
reset_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
* This must go first otherwise a really quick response will get reset.
*/
- sk->state = TCP_SYN_SENT;
+ tcp_set_state(sk,TCP_SYN_SENT);
/* sk->rtt = TCP_CONNECT_TIME;*/
sk->rto = TCP_TIMEOUT_INIT;
reset_timer(sk, TIME_WRITE, sk->rto); /* Timer for repeating the SYN until an answer */
{
sk->zapped=1;
sk->err = ECONNRESET;
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->shutdown = SHUTDOWN_MASK;
if (!sk->dead)
{
if (th->rst)
{
tcp_statistics.TcpEstabResets++;
- tcp_statistics.TcpCurrEstab--;
sk->zapped=1;
/* This means the thing should really be closed. */
sk->err = ECONNRESET;
* A reset with a fin just means that
* the data was not all read.
*/
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->shutdown = SHUTDOWN_MASK;
if (!sk->dead)
{
}
if (th->syn)
{
- tcp_statistics.TcpCurrEstab--;
tcp_statistics.TcpEstabResets++;
sk->err = ECONNRESET;
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->shutdown = SHUTDOWN_MASK;
tcp_reset(daddr, saddr, th, sk->prot, opt,dev, sk->ip_tos,sk->ip_ttl);
if (!sk->dead) {
{
tcp_statistics.TcpAttemptFails++;
sk->err = ECONNREFUSED;
- sk->state = TCP_CLOSE;
+ tcp_set_state(sk,TCP_CLOSE);
sk->shutdown = SHUTDOWN_MASK;
sk->zapped = 1;
if (!sk->dead)
{
if (th->syn)
{
- sk->state = TCP_SYN_RECV;
+ tcp_set_state(sk,TCP_SYN_RECV);
}
kfree_skb(skb, FREE_READ);
release_sock(sk);
return(0);
}
- tcp_statistics.TcpCurrEstab++;
- sk->state = TCP_ESTABLISHED;
+ tcp_set_state(sk,TCP_ESTABLISHED);
/*
* Now we need to finish filling out