Commit 917a96ae authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.87

parent fd46db1c
......@@ -505,7 +505,7 @@ S: 00200 Helsinki
S: Finland
N: Kai M"akisara
E: Kai.Makisara@vtt.fi
E: Kai.Makisara@metla.fi
D: SCSI Tape Driver
N: Hamish Macdonald
......
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 86
SUBLEVEL = 87
ARCH = i386
......
......@@ -162,42 +162,17 @@ static inline long load(long dev, unsigned long addr, unsigned long count)
}
/*
* Start the kernel:
* - switch to the proper PCB structure
* - switch to the proper ptbr
* - switch to the new kernel stack
* Start the kernel.
*/
static void runkernel(void)
{
struct pcb_struct * init_pcb = (struct pcb_struct *) INIT_PCB;
unsigned long oldptbr, *oldL1;
unsigned long newptbr, *newL1;
oldptbr = pcb_va->ptbr;
oldL1 = (unsigned long *) (PAGE_OFFSET + (oldptbr << PAGE_SHIFT));
newptbr = (SWAPPER_PGD - PAGE_OFFSET) >> PAGE_SHIFT;
newL1 = (unsigned long *) SWAPPER_PGD;
memcpy(newL1, oldL1, PAGE_SIZE);
newL1[1023] = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
*init_pcb = *pcb_va;
init_pcb->ksp = PAGE_SIZE + INIT_STACK;
init_pcb->ptbr = newptbr;
__asm__ __volatile__(
"bis %1,%1,$30\n\t"
"bis %0,%0,$26\n\t"
"bis %1,%1,$16\n\t"
".long %2\n\t"
"lda $16,-2($31)\n\t"
".long 51\n\t"
"ret ($26)"
: /* no outputs: it doesn't even return */
: "r" (START_ADDR),
"r" (init_pcb),
"i" (PAL_swpctx)
: "$16","$26");
"r" (PAGE_SIZE + INIT_STACK));
}
void start_kernel(void)
......
......@@ -47,6 +47,9 @@ void trap_init(void)
{
unsigned long gptr;
/*
* Tell PAL-code what global pointer we want in the kernel..
*/
__asm__("br %0,___tmp\n"
"___tmp:\tldgp %0,0(%0)"
: "=r" (gptr));
......
......@@ -9,7 +9,7 @@
.c.o:
$(CC) $(CFLAGS) -c $<
OBJS = __divqu.o __remqu.o __divlu.o __remlu.o
OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
......
/*
* linux/arch/alpha/lib/memset.c
*
* Copyright (C) 1995 Linus Torvalds
*/
/*
* These are only slightly optimized so far..
*/
#include <linux/types.h>
void * __constant_c_memset(void * s, unsigned long c, long count)
{
unsigned long xs = (unsigned long) s;
/*
* the first and last parts could be done with just one
* unaligned load/store, but I don't want to think about it
*/
while (count > 0 && (xs & 7)) {
*(char *) xs = c;
count--; xs++;
}
while (count > 7) {
*(unsigned long *) xs = c;
count -=8; xs += 8;
}
while (count > 0) {
*(char *) xs = c;
count--; xs++;
}
return s;
}
void * __memset(void * s,char c,size_t count)
{
char *xs = (char *) s;
while (count--)
*xs++ = c;
return s;
}
......@@ -86,17 +86,25 @@ void show_mem(void)
extern unsigned long free_area_init(unsigned long, unsigned long);
static void load_PCB(struct thread_struct * pcb)
{
__asm__ __volatile__(
"stq $30,0(%0)\n\t"
"bis %0,%0,$16\n\t"
".long %1"
: /* no outputs */
: "r" (pcb), "i" (PAL_swpctx)
: "$0", "$1", "$16", "$22", "$23", "$24", "$25");
}
/*
* paging_init() sets up the page tables: in the alpha version this actually
* unmaps the bootup page table (as we're now in KSEG, so we don't need it).
*
* The bootup sequence put the virtual page table into high memory: that
* means that we can change the L1 page table by just using VL1p below.
*/
#define VL1p ((unsigned long *) 0xffffffffffffe000)
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
int i;
unsigned long newptbr;
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
......@@ -122,8 +130,14 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
}
/* unmap the console stuff: we don't need it, and we don't want it */
for (i = 0; i < 1023; i++)
VL1p[i] = 0;
/* Also set up the real kernel PCB while we're at it.. */
memset((void *) ZERO_PGE, 0, PAGE_SIZE);
memset(swapper_pg_dir, 0, PAGE_SIZE);
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
init_task.tss.ptbr = newptbr;
load_PCB(&init_task.tss);
invalidate_all();
return start_mem;
}
......
......@@ -31,5 +31,11 @@ head.s: head.S $(TOPDIR)/include/linux/tasks.h
piggy.o: $(SYSTEM) xtract piggyback
./xtract $(SYSTEM) | gzip -9 | ./piggyback > piggy.o
xtract: xtract.c
$(HOSTCC) $(CFLAGS) -o xtract xtract.c
piggyback: xtract.c
$(HOSTCC) $(CFLAGS) -o piggyback piggyback.c
clean:
rm -f xtract piggyback vmlinux
......@@ -41,7 +41,7 @@ bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS n
if [ "$CONFIG_NET" = "y" ]; then
comment 'Networking options'
bool 'TCP/IP networking' CONFIG_INET y
if [ "$CONFIG_INET" "=" "y" ]; then
if [ "$CONFIG_INET" = "y" ]; then
bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n
bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n
bool 'IP firewalling' CONFIG_IP_FIREWALL n
......
......@@ -21,8 +21,13 @@
# In the future, some of these should be built conditionally.
#
OBJS := ll_rw_blk.o floppy.o ramdisk.o genhd.o
SRCS := ll_rw_blk.c floppy.c ramdisk.c genhd.c
OBJS := ll_rw_blk.o ramdisk.o genhd.o
SRCS := ll_rw_blk.c ramdisk.c genhd.c
ifdef CONFIG_BLK_DEV_FD
OBJS := $(OBJS) floppy.o
SRCS := $(SRCS) floppy.c
endif
ifdef CONFIG_CDU31A
OBJS := $(OBJS) cdu31a.o
......
......@@ -92,8 +92,6 @@
#include <linux/config.h>
#ifdef CONFIG_BLK_DEV_FD
#ifndef FD_MODULE
/* the following is the mask of allowed drives. By default units 2 and
* 3 of both floppy controllers are disabled, because switching on the
......@@ -3393,4 +3391,3 @@ static void floppy_release_irq_and_dma(void)
#endif
}
#endif
......@@ -7,11 +7,11 @@
* Also for the Longshine LCS-7260 drive.
* Also for the IBM "External ISA CD-Rom" drive.
* Not for the TEAC CD-55A drive (yet).
* Not for the CreativeLabs CD200 drive (yet).
* Not for the CreativeLabs CD200 drive (who knows?).
*
* NOTE: This is release 3.2.
* NOTE: This is release 3.3.
* It works with my SbPro & drive CR-521 V2.11 from 2/92
* and with the new CR-562-B V0.75 on a "naked" Panasonic
* and with the CR-562-B V0.75 on a "naked" Panasonic
* CI-101P interface. And vice versa.
*
*
......@@ -178,6 +178,8 @@
*
* 3.2 Still testing with CD200 and CD-55A drives.
*
* 3.3 Working with CD200 support. Maybe a simple read is already possible.
*
* TODO
*
* disk change detection
......@@ -193,12 +195,9 @@
* thread which brought additional hints and bug fixes.
*
*
* Copyright (C) 1993, 1994 Eberhard Moenkeberg <emoenke@gwdg.de>
* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg <emoenke@gwdg.de>
* or <eberhard_moenkeberg@rollo.central.de>
*
* The FTP-home of this driver is
* ftp.gwdg.de:/pub/linux/cdrom/drivers/sbpcd/.
*
* If you change this software, you should mail a .diff
* file with some description lines to emoenke@gwdg.de.
* I want to know about it.
......@@ -256,11 +255,13 @@
#include "blk.h"
#define VERSION "3.2 Eberhard Moenkeberg <emoenke@gwdg.de>"
#define VERSION "3.3 Eberhard Moenkeberg <emoenke@gwdg.de>"
/*
* still testing around...
*/
#define TEAC 0 /* set to 1 for TEAC CD-55A detection test (not more) */
#define MULTISESSION_BY_DRIVER 0 /* if set to 0 here, we need the counterpart
* in linux/fs/isofs/inode.c
*/
......@@ -282,7 +283,7 @@
#define PRINTK_BUG 0
#define TEST_STI 0
#define DISTRIBUTION 1
#define DISTRIBUTION 1 /* I use it with a 0 here */
#if 0
#define INLINE
......@@ -290,9 +291,6 @@
#define INLINE inline
#endif
#define TEAC 0
#define CD200 0
/*==========================================================================*/
/*
* provisions for more than 1 driver issues
......@@ -348,6 +346,7 @@
static int sbpcd_probe[] =
{
CDROM_PORT, SBPRO, /* probe with user's setup first */
#if DISTRIBUTION
0x230, 1, /* Soundblaster Pro and 16 (default) */
0x300, 0, /* CI-101P (default), WDH-7001C (default),
Galaxy (default), Reveal (one default) */
......@@ -381,6 +380,7 @@ static int sbpcd_probe[] =
0x290, 1, /* Soundblaster 16 */
0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
#endif
#endif DISTRIBUTION
};
#else
static int sbpcd_probe[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
......@@ -460,12 +460,9 @@ static int sbpcd_debug = (1<<DBG_INF) |
static int sbpcd_debug = (1<<DBG_INF) |
(1<<DBG_TOC) |
(1<<DBG_MUL) |
(1<<DBG_LCS) |
(1<<DBG_TEA) |
(1<<DBG_CD2) |
(1<<DBG_ID) |
(1<<DBG_UPC);
#endif
#endif DISTRIBUTION
static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */
static int sbpro_type = SBPRO;
static unsigned char setup_done = 0;
......@@ -559,7 +556,7 @@ static struct {
char drv_sel; /* drive select lines bits */
char drive_model[9];
char firmware_version[4];
u_char firmware_version[4];
char f_eject; /* auto-eject flag: 0 or 1 */
u_char *sbp_buf; /* Pointer to internal data buffer,
space allocated during sbpcd_init() */
......@@ -583,7 +580,11 @@ static struct {
u_char f_multisession;
u_int lba_multi;
#if MULTISESSION_BY_DRIVER
u_int last_redirect;
#endif MULTISESSION_BY_DRIVER
int first_session;
int last_session;
u_char audio_state;
u_int pos_audio_start;
......@@ -881,7 +882,7 @@ static int CDi_stat_loop(void)
return (-1);
}
/*==========================================================================*/
#if TEAC
#if TEAC-X
/*==========================================================================*/
static int tst_DataReady(void)
{
......@@ -910,7 +911,7 @@ static int tst_Attention(void)
return (0);
}
/*==========================================================================*/
#endif TEAC
#endif TEAC-X
/*==========================================================================*/
static int ResponseInfo(void)
{
......@@ -1048,7 +1049,7 @@ static void xx_ReadStatus(void)
else /* CD200, CD-55A */
{
}
if (!fam0_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
if (!fam0L_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
SBPCD_STI;
}
/*==========================================================================*/
......@@ -1073,18 +1074,25 @@ static int xx_ReadError(void)
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
}
else /* CD200, CD-55A */
else if (fam2_drive)
{
drvcmd[0]=CMD2_READ_ERR;
response_count=6;
flags_cmd_out=f_putcmd;
}
else /* CD-55A */
{
return (-1);
drvcmd[0]=CMDT_READ_ERR;
response_count=5;
flags_cmd_out=f_putcmd;
}
i=cmd_out(7);
DriveStruct[d].error_byte=0;
DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i));
if (i<0) return (i);
if (fam0_drive) i=1;
else if (fam1L_drive) i=2;
else /* CD200, CD-55A */
{
}
else i=2;
DriveStruct[d].error_byte=infobuf[i];
DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DriveStruct[d].error_byte,DriveStruct[d].error_byte));
i=sta2err(infobuf[i]);
......@@ -1163,7 +1171,7 @@ static int xx_Seek(u_int pos, char f_blk_msf)
if (f_blk_msf>1) return (-3);
if (fam0_drive)
{
drvcmd[0]=CMD0_SEEK; /* same as CMD1_ and CMDL_ */
drvcmd[0]=CMD0_SEEK;
if (f_blk_msf==1) pos=msf2blk(pos);
drvcmd[2]=(pos>>16)&0x00FF;
drvcmd[3]=(pos>>8)&0x00FF;
......@@ -1183,8 +1191,19 @@ static int xx_Seek(u_int pos, char f_blk_msf)
else
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else if (fam2_drive)
{
drvcmd[0]=CMD2_SEEK;
if (f_blk_msf==0) pos=blk2msf(pos);
drvcmd[2]=(pos>>16)&0x00FF;
drvcmd[3]=(pos>>16)&0x00FF;
drvcmd[4]=(pos>>8)&0x00FF;
drvcmd[5]=pos&0x00FF;
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else /* CD-55A */
{
return (-1);
}
response_count=0;
i=cmd_out(7);
......@@ -1209,8 +1228,15 @@ static int xx_SpinUp(void)
drvcmd[0]=CMD1_SPINUP;
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else if (fam2_drive)
{
drvcmd[0]=CMD2_TRAY_CTL;
drvcmd[4]=0x01;
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
}
else /* CD-55A */
{
return (-1);
}
response_count=0;
i=cmd_out(7);
......@@ -1224,21 +1250,27 @@ static int yy_SpinDown(void)
if (fam0_drive) return (-3);
clr_cmdbuf();
response_count=0;
if (fam1_drive)
{
drvcmd[0]=CMD1_SPINDOWN;
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
response_count=0;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_TRAY_CTL;
drvcmd[4]=0x02; /* "eject" */
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else if (famL_drive)
{
drvcmd[0]=CMDL_SPINDOWN;
drvcmd[1]=1;
flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
response_count=0;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
i=cmd_out(7);
return (i);
......@@ -1250,13 +1282,35 @@ static int yy_SetSpeed(u_char speed, u_char x1, u_char x2)
if (fam0L_drive) return (-3);
clr_cmdbuf();
response_count=0;
if (fam1_drive)
{
drvcmd[0]=CMD1_SETMODE;
drvcmd[1]=0x03;
drvcmd[2]=speed;
drvcmd[3]=x1;
drvcmd[4]=x2;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
response_count=0;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_SETSPEED;
if (speed&speed_auto)
{
drvcmd[2]=0xFF;
drvcmd[3]=0xFF;
}
else
{
drvcmd[2]=0;
drvcmd[3]=150;
}
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else /* CD-55A */
{
return (-1);
}
i=cmd_out(7);
return (i);
}
......@@ -1315,6 +1369,22 @@ static int xx_SetVolume(void)
drvcmd[6]=value1;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else if (fam2_drive)
{
control0=channel0+1;
control1=channel1+1;
value0=(volume0>volume1)?volume0:volume1;
value1=value0;
if (volume0==0) control0=0;
if (volume1==0) control1=0;
drvcmd[0]=CMD2_SETMODE;
drvcmd[1]=0x0E;
drvcmd[3]=control0;
drvcmd[4]=value0;
drvcmd[5]=control1;
drvcmd[6]=value1;
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else if (famL_drive)
{
if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
......@@ -1392,8 +1462,9 @@ static int xx_SetVolume(void)
drvcmd[5]=value0;
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
response_count=0;
i=cmd_out(7);
......@@ -1418,17 +1489,25 @@ static int xy_DriveReset(void)
int i;
DPRINTF((DBG_RES,"SBPCD: xy_DriveReset called.\n"));
clr_cmdbuf();
response_count=0;
if (fam0L_drive) OUT(CDo_reset,0x00);
else if (fam1_drive)
{
clr_cmdbuf();
drvcmd[0]=CMD1_RESET;
flags_cmd_out=f_putcmd;
response_count=0;
i=cmd_out(7);
}
else /* CD200, CD-55A */
else if (fam2_drive)
{
drvcmd[0]=CMD2_RESET;
flags_cmd_out=f_putcmd;
i=cmd_out(7);
OUT(CDo_reset,0x00);
}
else /* CD-55A */
{
return (-1);
}
if (famL_drive) sbp_sleep(500); /* wait 5 seconds */
else sbp_sleep(100); /* wait a second */
......@@ -1483,14 +1562,23 @@ static int xx_Pause_Resume(int pau_res)
int i;
clr_cmdbuf();
response_count=0;
if (fam1_drive)
{
drvcmd[0]=CMD1_PAU_RES;
if (pau_res!=1) drvcmd[1]=0x80;
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_PAU_RES;
if (pau_res!=1) drvcmd[2]=0x01;
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_PAU_RES;
if (pau_res!=1) drvcmd[1]=0x80;
if (famL_drive)
flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
f_obey_p_check|f_bit1;
......@@ -1498,11 +1586,10 @@ static int xx_Pause_Resume(int pau_res)
flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
f_obey_p_check;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
if (pau_res!=1) drvcmd[1]=0x80;
response_count=0;
i=cmd_out(7);
return (i);
}
......@@ -1515,22 +1602,28 @@ static int yy_LockDoor(char lock)
DPRINTF((DBG_LCK,"SBPCD: yy_LockDoor: %d (drive %d)\n", lock, d));
DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d before\n", st_door_locked));
clr_cmdbuf();
response_count=0;
if (fam1_drive)
{
drvcmd[0]=CMD1_LOCK_CTL;
if (lock==1) drvcmd[1]=0x01;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
response_count=0;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_LOCK_CTL;
if (lock==1) drvcmd[4]=0x01;
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else if (famL_drive)
{
drvcmd[0]=CMDL_LOCK_CTL;
if (lock==1) drvcmd[1]=0x01;
flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
response_count=0;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
i=cmd_out(7);
DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d after\n", st_door_locked));
......@@ -1546,21 +1639,29 @@ static int yy_CloseTray(void)
DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d before\n", st_door_closed));
clr_cmdbuf();
response_count=0;
if (fam1_drive)
{
drvcmd[0]=CMD1_TRAY_CTL;
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_TRAY_CTL;
drvcmd[1]=0x01;
drvcmd[4]=0x03; /* "insert" */
flags_cmd_out=f_putcmd|f_ResponseStatus;
}
else if (famL_drive)
{
drvcmd[0]=CMDL_TRAY_CTL;
flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
f_ResponseStatus|f_obey_p_check|f_bit1;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
response_count=0;
i=cmd_out(7);
DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d after\n", st_door_closed));
return (i);
......@@ -1580,6 +1681,14 @@ static int xx_ReadSubQ(void)
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
response_count=11;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_READSUBQ;
drvcmd[1]=0x02;
drvcmd[3]=0x01;
flags_cmd_out=f_putcmd;
response_count=10;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_READSUBQ;
......@@ -1590,13 +1699,14 @@ static int xx_ReadSubQ(void)
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
response_count=13;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
i=cmd_out(7);
if (i<0) return (i);
DPRINTF((DBG_SQ,"SBPCD: xx_ReadSubQ:"));
for (i=0;i<(fam1_drive?11:13);i++)
for (i=0;i<response_count;i++)
{
DPRINTF((DBG_SQ," %02X", infobuf[i]));
}
......@@ -1627,34 +1737,34 @@ static int xx_ModeSense(void)
{
int i;
if (fam2_drive) return (0);
DriveStruct[d].diskstate_flags &= ~frame_size_bit;
clr_cmdbuf();
if (fam1_drive)
{
drvcmd[0]=CMD1_GETMODE;
drvcmd[1]=0x00;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
response_count=5;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_GETMODE;
drvcmd[1]=0x00;
if (famL_drive)
flags_cmd_out=f_putcmd;
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
response_count=2;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
i=cmd_out(7);
if (i<0) return (i);
i=0;
if (fam0L_drive) DriveStruct[d].sense_byte=0;
if (fam1_drive) DriveStruct[d].sense_byte=infobuf[i++];
else /* CD200, CD-55A */
else if (fam0L_drive) DriveStruct[d].sense_byte=0;
else /* CD-55A */
{
}
DriveStruct[d].frame_size=make16(infobuf[i],infobuf[i+1]);
......@@ -1675,6 +1785,7 @@ static int xx_ModeSelect(int framesize)
{
int i;
if (fam2_drive) return (0);
DriveStruct[d].diskstate_flags &= ~frame_size_bit;
clr_cmdbuf();
DriveStruct[d].frame_size=framesize;
......@@ -1705,8 +1816,9 @@ static int xx_ModeSelect(int framesize)
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
response_count=0;
i=cmd_out(7);
......@@ -1731,6 +1843,13 @@ static int xx_TellVolume(void)
response_count=5;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_GETMODE;
drvcmd[1]=0x0E;
response_count=5;
flags_cmd_out=f_putcmd;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_GETMODE;
......@@ -1741,8 +1860,9 @@ static int xx_TellVolume(void)
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
i=cmd_out(7);
if (i<0) return (i);
......@@ -1765,6 +1885,13 @@ static int xx_TellVolume(void)
chan0 >>= 1;
chan1 >>= 1;
}
else if (fam2_drive)
{
chan0=infobuf[1];
vol0=infobuf[2];
chan1=infobuf[3];
vol1=infobuf[4];
}
else if (famL_drive)
{
chan0=0;
......@@ -1804,26 +1931,18 @@ static int xx_TellVolume(void)
}
}
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
DriveStruct[d].vol_chan0=chan0;
DriveStruct[d].vol_ctrl0=vol0;
DriveStruct[d].vol_chan1=chan1;
DriveStruct[d].vol_ctrl1=vol1;
if (fam01_drive)
{
DriveStruct[d].vol_chan2=2;
DriveStruct[d].vol_ctrl2=0xFF;
DriveStruct[d].vol_chan3=3;
DriveStruct[d].vol_ctrl3=0xFF;
}
else if (famL_drive)
{
}
else /* CD200, CD-55A */
{
}
DriveStruct[d].diskstate_flags |= volume_bit;
return (0);
}
......@@ -1833,31 +1952,39 @@ static int xx_ReadCapacity(void)
{
int i;
if (famL_drive) return (0);
DriveStruct[d].diskstate_flags &= ~cd_size_bit;
clr_cmdbuf();
if (fam1_drive)
{
drvcmd[0]=CMD1_CAPACITY;
response_count=5;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else if (fam0L_drive)
else if (fam2_drive)
{
drvcmd[0]=CMD2_CAPACITY;
response_count=8;
flags_cmd_out=f_putcmd;
}
else if (fam0_drive)
{
drvcmd[0]=CMD0_CAPACITY;
response_count=5;
if(famL_drive)
flags_cmd_out=f_putcmd;
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
response_count=5;
i=cmd_out(7);
if (i<0) return (i);
DriveStruct[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
if (fam1_drive) DriveStruct[d].CDsize_blk=msf2blk(DriveStruct[d].CDsize_blk);
DriveStruct[d].CDsize_frm = (DriveStruct[d].CDsize_blk * make16(infobuf[3],infobuf[4])) / CD_FRAMESIZE;
DriveStruct[d].CDsize_blk += 151;
if (fam1_drive) DriveStruct[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_BLOCK_OFFSET;
else if (fam0_drive) DriveStruct[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
else if (fam2_drive) DriveStruct[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
DriveStruct[d].diskstate_flags |= cd_size_bit;
return (0);
}
......@@ -1871,30 +1998,93 @@ static int xx_ReadTocDescr(void)
if (fam1_drive)
{
drvcmd[0]=CMD1_DISKINFO;
response_count=6;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_DISKINFO;
response_count=6;
if(famL_drive)
flags_cmd_out=f_putcmd;
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else if (fam2_drive)
{
/* possibly longer timeout periods necessary */
DriveStruct[d].f_multisession=0;
drvcmd[0]=CMD2_DISKINFO;
drvcmd[1]=0x02;
drvcmd[2]=0xAB;
drvcmd[3]=0xFF; /* session */
response_count=8;
flags_cmd_out=f_putcmd;
}
else /* CD-55A */
{
return (-1);
}
response_count=6;
i=cmd_out(7);
if (i<0) return (i);
DriveStruct[d].xa_byte=infobuf[0];
if (fam2_drive)
{
DriveStruct[d].first_session=infobuf[1];
DriveStruct[d].last_session=infobuf[2];
DriveStruct[d].n_first_track=infobuf[3];
DriveStruct[d].n_last_track=infobuf[4];
if (DriveStruct[d].first_session!=DriveStruct[d].last_session)
{
DriveStruct[d].f_multisession=1;
DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
}
#if 0
if (DriveStruct[d].first_session!=DriveStruct[d].last_session)
{
if (DriveStruct[d].last_session<=20)
zwanzig=DriveStruct[d].last_session+1;
else zwanzig=20;
for (count=DriveStruct[d].first_session;count<zwanzig;count++)
{
drvcmd[0]=CMD2_DISKINFO;
drvcmd[1]=0x02;
drvcmd[2]=0xAB;
drvcmd[3]=count;
response_count=8;
flags_cmd_out=f_putcmd;
i=cmd_out(7);
if (i<0) return (i);
DriveStruct[d].msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
}
DriveStruct[d].diskstate_flags |= multisession_bit;
}
#endif
drvcmd[0]=CMD2_DISKINFO;
drvcmd[1]=0x02;
drvcmd[2]=0xAA;
drvcmd[3]=0xFF;
response_count=5;
flags_cmd_out=f_putcmd;
i=cmd_out(7);
if (i<0) return (i);
DriveStruct[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
}
else
{
DriveStruct[d].n_first_track=infobuf[1];
DriveStruct[d].n_last_track=infobuf[2];
DriveStruct[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
if (famL_drive) DriveStruct[d].CDsize_frm=DriveStruct[d].size_blk+1;
}
DriveStruct[d].diskstate_flags |= toc_bit;
DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
DriveStruct[d].xa_byte,DriveStruct[d].n_first_track,DriveStruct[d].n_last_track,DriveStruct[d].size_msf));
DriveStruct[d].xa_byte,
DriveStruct[d].n_first_track,
DriveStruct[d].n_last_track,
DriveStruct[d].size_msf));
return (0);
}
/*==========================================================================*/
......@@ -1906,30 +2096,49 @@ static int xx_ReadTocEntry(int num)
if (fam1_drive)
{
drvcmd[0]=CMD1_READTOC;
response_count=8;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else if (fam2_drive)
{
/* possibly longer timeout periods necessary */
drvcmd[0]=CMD2_DISKINFO;
drvcmd[1]=0x02;
response_count=5;
flags_cmd_out=f_putcmd;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_READTOC;
drvcmd[1]=0x02;
response_count=8;
if(famL_drive)
flags_cmd_out=f_putcmd;
else
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
drvcmd[2]=num;
response_count=8;
i=cmd_out(7);
if (i<0) return (i);
if (fam2_drive) i=0;
else
{
DriveStruct[d].TocEnt_nixbyte=infobuf[0];
DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]);
DriveStruct[d].TocEnt_number=infobuf[2];
DriveStruct[d].TocEnt_format=infobuf[3];
i=1;
}
DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
if (!(fam2_drive))
{
DriveStruct[d].TocEnt_number=infobuf[i++];
DriveStruct[d].TocEnt_format=infobuf[i];
}
if (fam1_drive) i=4;
else i=5;
else if (fam0L_drive) i=5;
else if (fam2_drive) i=2;
DriveStruct[d].TocEnt_address=make32(make16(0,infobuf[i]),
make16(infobuf[i+1],infobuf[i+2]));
DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
......@@ -1952,6 +2161,7 @@ static int xx_ReadPacket(void)
flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
else /* CD200, CD-55A */
{
return (-1);
}
i=cmd_out(7);
return (i);
......@@ -1973,6 +2183,7 @@ static int convert_UPC(u_char *p)
}
else /* CD200, CD-55A */
{
return (-1);
}
}
DriveStruct[d].UPC_buf[6] &= 0xF0;
......@@ -2016,6 +2227,7 @@ static int xx_ReadUPC(void)
}
else /* CD200, CD-55A */
{
return (-1);
}
i=cmd_out(7);
if (i<0) return (i);
......@@ -2067,10 +2279,11 @@ static int yy_CheckMultiSession(void)
{
int i;
if (fam2_drive) return (0);
DriveStruct[d].f_multisession=0;
clr_cmdbuf();
DriveStruct[d].lba_multi=0;
if (fam0_drive) return (0);
clr_cmdbuf();
if (fam1_drive)
{
drvcmd[0]=CMD1_MULTISESS;
......@@ -2083,11 +2296,9 @@ static int yy_CheckMultiSession(void)
DriveStruct[d].f_multisession=1;
DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
make16(infobuf[2],infobuf[3])));
#if MULTISESSION_BY_DRIVER
DriveStruct[d].last_redirect=19;
/* preliminary - has to get adjusted the following way:
* look at the first byte of frames 17 ff. until 0xFF is seen
* the frame before this one is the last continuation frame
*/
#endif MULTISESSION_BY_DRIVER
DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X (%d)\n",
infobuf[0], infobuf[1], infobuf[2],
infobuf[3], infobuf[4], infobuf[5],
......@@ -2113,15 +2324,14 @@ static int yy_CheckMultiSession(void)
{
DPRINTF((DBG_MUL,"SBPCD: MultiSession base: %06X\n", DriveStruct[d].lba_multi));
DriveStruct[d].f_multisession=1;
#if MULTISESSION_BY_DRIVER
DriveStruct[d].last_redirect=19;
/* preliminary - has to get adjusted the following way:
* look at the first byte of frames 17 ff. until 0xFF is seen;
* the frame before this one is the last repetition frame.
*/
#endif MULTISESSION_BY_DRIVER
}
}
else /* CD200, CD-55A */
else /* CD-55A */
{
return (-1);
}
return (0);
}
......@@ -2198,7 +2408,7 @@ static void check_datarate(void)
#endif CDMKE
}
/*==========================================================================*/
#if TEAC
#if TEAC-X
/*==========================================================================*/
static void teac_reset(int drv_id)
{
......@@ -2242,7 +2452,7 @@ static int find_teac_drives(void)
return (found);
}
/*==========================================================================*/
#endif TEAC
#endif TEAC-X
/*==========================================================================*/
/*==========================================================================*/
#ifdef CD200
......@@ -2310,11 +2520,31 @@ static void ask_mail(void)
static int check_version(void)
{
int i, j;
u_char lcs_firm[][4]={"A4F4","A E1"};
DPRINTF((DBG_INI,"SBPCD: check_version entered.\n"));
DriveStruct[d].drv_type=0;
/* check for CD200 first */
#if TEAC
/* check for CD-55A */
clr_cmdbuf();
drvcmd[0]=CMDT_READ_ERR;
response_count=5;
flags_cmd_out=f_putcmd;
i=cmd_out(7);
if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READERR returns %d (ok anyway).\n",i));
/* read drive version */
clr_cmdbuf();
for (i=0;i<12;i++) infobuf[i]=0;
if (sbpro_type==1) OUT(CDo_sel_i_d,0);
response_count=12; /* may be too much */
drvcmd[0]=CMDT_READ_VER;
drvcmd[4]=response_count;
flags_cmd_out=f_putcmd;
i=cmd_out(10); /* possibly only 6 */
if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READ_VER returns %d\n",i));
#else
/* check for CD200 */
clr_cmdbuf();
drvcmd[0]=CMD2_READ_ERR;
response_count=9;
......@@ -2335,27 +2565,7 @@ static int check_version(void)
flags_cmd_out=f_putcmd;
i=cmd_out(7);
if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD2_READ_VER returns %d\n",i));
if (i<0)
{
/* check for CD-55A */
clr_cmdbuf();
drvcmd[0]=CMDT_READ_ERR;
response_count=5;
flags_cmd_out=f_putcmd;
i=cmd_out(7);
if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READERR returns %d (ok anyway).\n",i));
/* read drive version */
clr_cmdbuf();
for (i=0;i<12;i++) infobuf[i]=0;
if (sbpro_type==1) OUT(CDo_sel_i_d,0);
response_count=12; /* may be too much */
drvcmd[0]=CMDT_READ_VER;
drvcmd[4]=response_count;
flags_cmd_out=f_putcmd;
i=cmd_out(10); /* possibly only 6 */
if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READ_VER returns %d\n",i));
}
#endif TEAC
if (i>=0) /* either from CD200 or CD-55A */
{
for (i=0, j=0;i<12;i++) j+=infobuf[i];
......@@ -2473,12 +2683,14 @@ static int check_version(void)
for (j=0;j<4;j++) DriveStruct[d].firmware_version[j]=infobuf[i+j];
if (famL_drive)
{
for (i=0;i<2;i++)
{
for (j=0;j<4;j++)
if (DriveStruct[d].firmware_version[j]!=lcs_firm[i][j]) break;
if (j==4) break;
}
if (j!=4) ask_mail();
DriveStruct[d].drv_type=drv_260;
if ((DriveStruct[d].firmware_version[0]!='A') ||
(DriveStruct[d].firmware_version[1]!='4') ||
(DriveStruct[d].firmware_version[2]!='F') ||
(DriveStruct[d].firmware_version[3]!='4'))
ask_mail();
}
else if (famT_drive)
{
......@@ -2511,13 +2723,9 @@ static int check_version(void)
{
printk("\n\nSBPCD: new drive CD200 (%s)detected.\n",
DriveStruct[d].firmware_version);
printk("SBPCD: support is not fulfilled yet - drive gets ignored.\n");
printk("SBPCD: support is not fulfilled yet.\n");
if (j!=101) /* only 1.01 known at time */
ask_mail();
else
printk("SBPCD: just wait some days...\n\n");
DriveStruct[d].drv_type=0;
return (-1);
}
}
DPRINTF((DBG_LCS,"SBPCD: drive type %02X\n",DriveStruct[d].drv_type));
......@@ -3284,9 +3492,10 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
int error_flag;
DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n"));
#if 0
if (fam0L_drive) return (-EINVAL);
#endif
if (fam0_drive) return (-EINVAL);
if (famL_drive) return (-EINVAL);
if (fam2_drive) return (-EINVAL);
if (famT_drive) return (-EINVAL);
if (DriveStruct[d].aud_buf==NULL) return (-EINVAL);
i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
if (i) return (i);
......@@ -3717,13 +3926,21 @@ static void sbp_read_cmd(void)
}
else if (fam1_drive)
{
drvcmd[0]=CMD1_READ; /* "read frames", new drives */
drvcmd[0]=CMD1_READ;
lba2msf(block,&drvcmd[1]); /* msf-bin format required */
drvcmd[4]=0;
drvcmd[5]=0;
drvcmd[6]=DriveStruct[d].sbp_read_frames;
}
else /* CD200, CD-55A */
else if (fam2_drive)
{
drvcmd[0]=CMD2_READ;
lba2msf(block,&drvcmd[1]); /* msf-bin format required */
drvcmd[4]=0;
drvcmd[5]=DriveStruct[d].sbp_read_frames;
drvcmd[6]=0x02;
}
else /* CD-55A */
{
}
SBPCD_CLI;
......
......@@ -94,9 +94,9 @@ endif
dep:
$(CPP) -M $(SRCS) > .depend
#ifdef MODULES
ifdef MODULES
$(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend
#endif
endif
dummy:
......
......@@ -304,11 +304,16 @@ static void rw_intr (Scsi_Cmnd * SCpnt)
* kraxel@cs.tu-berlin.de (Gerd Knorr)
*/
#define DEBUG
static void sr_photocd(struct inode *inode)
{
unsigned long sector,min,sec,frame;
unsigned char buf[40];
int rc;
unsigned char buf[40]; /* the buffer for the ioctl */
unsigned char *cmd; /* the scsi-command */
unsigned char *send; /* the data we send to the drive ... */
unsigned char *rec; /* ... and get back */
int rc,is_xa;
if (!suser()) {
/* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed for me.
......@@ -322,6 +327,7 @@ static void sr_photocd(struct inode *inode)
return;
}
cmd = rec = &buf[8];
switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
case SCSI_MAN_NEC:
......@@ -329,22 +335,24 @@ static void sr_photocd(struct inode *inode)
printk("sr_photocd: use NEC code\n");
#endif
memset(buf,0,40);
*((unsigned long*)buf) = 0;
*((unsigned long*)buf+1) = 0x16;
buf[8+0] = 0xde;
buf[8+1] = 0x03;
buf[8+2] = 0xb0;
*((unsigned long*)buf) = 0x0; /* we send nothing... */
*((unsigned long*)buf+1) = 0x16; /* and receive 0x16 bytes */
cmd[0] = 0xde;
cmd[1] = 0x03;
cmd[2] = 0xb0;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
SCSI_IOCTL_SEND_COMMAND, buf);
if (rc != 0) {
printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
sector = 0;
} else {
min = (unsigned long)buf[8+15]/16*10 + (unsigned long)buf[8+15]%16;
sec = (unsigned long)buf[8+16]/16*10 + (unsigned long)buf[8+16]%16;
frame = (unsigned long)buf[8+17]/16*10 + (unsigned long)buf[8+17]%16;
sector = min*60*75 + sec*75 + frame;
min = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
sec = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
/* if rec[14] is'nt 0xb0, the drive does not support multisession CD's, use zero */
sector = (0xb0 == rec[14]) ? min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame : 0;
#ifdef DEBUG
printk("NEC: (%2x) %2li:%02li:%02li = %li\n",buf[8+14],min,sec,frame,sector);
if (sector) {
printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
}
......@@ -357,43 +365,71 @@ static void sr_photocd(struct inode *inode)
printk("sr_photocd: use TOSHIBA code\n");
#endif
/* first I do a set_density-call (for reading XA-sectors) ... */
/* we request some disc information (is it a XA-CD ?,
where starts the last session ?) */
memset(buf,0,40);
*((unsigned long*)buf) = 12;
*((unsigned long*)buf+1) = 12;
buf[8+0] = 0x15;
buf[8+1] = (1 << 4);
buf[8+4] = 12;
buf[14+ 3] = 0x08;
buf[14+ 4] = 0x83;
buf[14+10] = 0x08;
*((unsigned long*)buf) = 0;
*((unsigned long*)buf+1) = 4; /* we receive 4 bytes from the drive */
cmd[0] = 0xc7;
cmd[1] = 3;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
SCSI_IOCTL_SEND_COMMAND, buf);
if (rc != 0) {
printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
sector = 0;
break; /* if the first ioctl fails, we don't call the secound one */
}
is_xa = (rec[0] == 0x20);
#ifdef DEBUG
printk("sr_photocd: TOSHIBA %x\n",rec[0]);
#endif
min = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
sec = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
frame = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
if (sector) {
sector -= CD_BLOCK_OFFSET;
#ifdef DEBUG
printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
#endif
}
/* ... and then I ask, if there is a multisession-Disk */
/* now we do a get_density... */
memset(buf,0,40);
*((unsigned long*)buf) = 0;
*((unsigned long*)buf+1) = 4;
buf[8+0] = 0xc7;
buf[8+1] = 3;
*((unsigned long*)buf+1) = 12;
cmd[0] = 0x1a;
cmd[2] = 1;
cmd[4] = 12;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
SCSI_IOCTL_SEND_COMMAND, buf);
if (rc != 0) {
printk("sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
sector = 0;
} else {
min = (unsigned long)buf[8+1]/16*10 + (unsigned long)buf[8+1]%16;
sec = (unsigned long)buf[8+2]/16*10 + (unsigned long)buf[8+2]%16;
frame = (unsigned long)buf[8+3]/16*10 + (unsigned long)buf[8+3]%16;
sector = min*60*75 + sec*75 + frame;
if (sector) {
sector -= CD_BLOCK_OFFSET;
break;
}
#ifdef DEBUG
printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
printk("sr_photocd: get_density: 0x%x\n",rec[4]);
#endif
/* ...and only if nessesary a set_density */
if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) {
#ifdef DEBUG
printk("sr_photocd: doing set_density\n");
#endif
memset(buf,0,40);
*((unsigned long*)buf) = 12; /* sending 12 bytes... */
*((unsigned long*)buf+1) = 0;
cmd[0] = 0x15;
cmd[1] = (1 << 4);
cmd[4] = 12;
send = &cmd[6]; /* this is a 6-Byte command */
send[ 3] = 0x08; /* the data for the command */
send[ 4] = (is_xa) ? 0x81 : 0; /* density 0x81 for XA-CD's, 0 else */
send[10] = 0x08;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
SCSI_IOCTL_SEND_COMMAND, buf);
if (rc != 0) {
printk("sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
}
}
break;
......@@ -412,6 +448,8 @@ static void sr_photocd(struct inode *inode)
return;
}
#undef DEBUG
static int sr_open(struct inode * inode, struct file * filp)
{
if(MINOR(inode->i_rdev) >= sr_template.nr_dev ||
......@@ -427,9 +465,7 @@ static int sr_open(struct inode * inode, struct file * filp)
if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
(*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
#if 1 /* don't use for now - it doesn't seem to work for everybody */
sr_photocd(inode);
#endif
/* If this device did not have media in the drive at boot time, then
we would have been unable to get the sector size. Check to see if
......@@ -587,15 +623,6 @@ work around the fact that the buffer cache has a block size of 1024,
and we have 2048 byte sectors. This code should work for buffers that
are any multiple of 512 bytes long. */
#if 1
/* Here we redirect the volume descriptor block of the CD-ROM.
* Necessary for multisession CD's, until the isofs-routines
* handle this via the CDROMMULTISESSION_SYS call
*/
if (block >= 64 && block < 68) {
block += scsi_CDs[dev].mpcd_sector*4; }
#endif
SCpnt->use_sg = 0;
if (SCpnt->host->sg_tablesize > 0 &&
......
......@@ -11,7 +11,7 @@
Copyright 1992, 1993, 1994, 1995 Kai Makisara
email Kai.Makisara@metla.fi
Last modified: Wed Jan 11 22:02:20 1995 by root@kai.home
Last modified: Thu Jan 19 23:28:05 1995 by makisara@kai.home
*/
#include <linux/fs.h>
......@@ -1546,7 +1546,7 @@ st_int_ioctl(struct inode * inode,struct file * file,
STp->moves_after_eof = 0;
else
STp->moves_after_eof = 1;
if (!ioctl_result) {
if (!ioctl_result) { /* SCSI command successful */
if (cmd_in != MTSEEK) {
STp->drv_block = blkno;
(STp->mt_status)->mt_fileno = fileno;
......@@ -1587,8 +1587,10 @@ st_int_ioctl(struct inode * inode,struct file * file,
STp->eof = ST_NOEOF;
STp->eof_hit = 0;
}
} else {
} else { /* SCSI command was not completely successful */
if (SCpnt->sense_buffer[2] & 0x40) {
if (cmd_in != MTBSF && cmd_in != MTBSFM &&
cmd_in != MTBSR && cmd_in != MTBSS)
STp->eof = ST_EOM_OK;
STp->eof_hit = 0;
STp->drv_block = 0;
......@@ -1884,7 +1886,6 @@ static void st_init()
{
int i;
Scsi_Tape * STp;
Scsi_Device * SDp;
static int st_registered = 0;
if (st_template.dev_noticed == 0) return;
......
......@@ -901,6 +901,7 @@ static struct {
{ NFSERR_NOENT, ENOENT },
{ NFSERR_IO, errno_NFSERR_IO },
{ NFSERR_NXIO, ENXIO },
{ NFSERR_EAGAIN, EAGAIN },
{ NFSERR_ACCES, EACCES },
{ NFSERR_EXIST, EEXIST },
{ NFSERR_NODEV, ENODEV },
......
......@@ -17,14 +17,21 @@ __asm__ __volatile__( \
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 13
#define PGDIR_SHIFT 23
#define PMD_SHIFT 23
#define PGDIR_SHIFT 33
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PMD_MASK (~(PMD_SIZE-1))
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#ifdef __KERNEL__
#define PAGE_OFFSET 0xFFFFFC0000000000
#define MAP_NR(addr) (((addr) - PAGE_OFFSET) >> PAGE_SHIFT)
#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
#define MAP_PAGE_RESERVED (1<<31)
typedef unsigned int mem_map_t;
......@@ -37,10 +44,12 @@ typedef unsigned int mem_map_t;
* These are used to make use of C type-checking..
*/
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
#define pte_val(x) ((x).pte)
#define pmd_val(x) ((x).pmd)
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
......@@ -53,10 +62,12 @@ typedef struct { unsigned long pgprot; } pgprot_t;
* .. while these make it easier on the compiler
*/
typedef unsigned long pte_t;
typedef unsigned long pmd_t;
typedef unsigned long pgd_t;
typedef unsigned long pgprot_t;
#define pte_val(x) (x)
#define pmd_val(x) (x)
#define pgd_val(x) (x)
#define pgprot_val(x) (x)
......@@ -141,7 +152,7 @@ typedef unsigned long pgprot_t;
* for zero-mapped memory areas etc..
*/
extern pte_t __bad_page(void);
extern pte_t * __bad_pagetable(void);
extern pmd_t * __bad_pagetable(void);
extern unsigned long __zero_page(void);
......@@ -152,12 +163,6 @@ extern unsigned long __zero_page(void);
/* number of bits that fit into a memory pointer */
#define BITS_PER_PTR (8*sizeof(unsigned long))
/* to mask away the intra-page address bits */
#define PAGE_MASK (~(PAGE_SIZE-1))
/* to mask away the intra-page address bits */
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
......@@ -171,23 +176,12 @@ extern unsigned long __zero_page(void);
#define PAGE_PTR(address) \
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
/* the no. of pointers that fit on a page */
#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*))
/* to set the page-dir */
extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
{
tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT;
if (tsk == current)
invalidate();
}
/* This one will go away */
#define PTRS_PER_PAGE 1024
/* to find an entry in a page-table-directory */
extern inline pgd_t * PAGE_DIR_OFFSET(struct task_struct * tsk, unsigned long address)
{
return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) +
((address >> 33) & PTR_MASK);
}
#define PTRS_PER_PTE 1024
#define PTRS_PER_PMD 1024
#define PTRS_PER_PGD 1024
extern unsigned long high_memory;
......@@ -196,23 +190,37 @@ extern unsigned long high_memory;
* and a page entry and page directory to the page they refer to.
*/
extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
{ pte_t pte; pte_val(pte) = (page << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
{ pte_t pte; pte_val(pte) = ((page-PAGE_OFFSET) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
extern inline void pgd_set(pgd_t * pgdp, pte_t * ptep)
{ pgd_val(*pgdp) = _PAGE_TABLE | (((unsigned long) ptep) << (32-PAGE_SHIFT)); }
extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
{ pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
{ pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
extern inline unsigned long pte_page(pte_t pte)
{ return PAGE_OFFSET + ((pte_val(pte) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
extern inline unsigned long pte_page(pte_t pte) { return (pte_val(pte) & _PFN_MASK) >> (32-PAGE_SHIFT); }
extern inline unsigned long pgd_page(pgd_t pgd) { return (pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT); }
extern inline pte_t * pmd_page(pmd_t pmd)
{ return (pte_t *) (PAGE_OFFSET + ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT))); }
extern inline pmd_t * pgd_page(pgd_t pgd)
{ return (pmd_t *) (PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT))); }
extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || (unsigned long) pmd_page(pmd) > high_memory; }
extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; }
extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || (unsigned long) pgd_page(pgd) > high_memory; }
extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; }
extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
......@@ -240,6 +248,83 @@ extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; retur
extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; }
extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; }
/* to set the page-dir */
extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
{
tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT;
if (tsk == current)
invalidate();
}
/* to find an entry in a page-table-directory */
extern inline pgd_t * PAGE_DIR_OFFSET(struct task_struct * tsk, unsigned long address)
{
return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) +
((address >> 33) & (PTRS_PER_PGD - 1));
}
/* to find an entry in the second-level page-table-directory */
extern inline pmd_t * PAGE_MIDDLE_OFFSET(pgd_t * dir, unsigned long address)
{
return pgd_page(*dir) + ((address >> 23) & (PTRS_PER_PMD - 1));
}
/* to find an entry in the third-level page-table-directory */
extern inline pte_t * PAGE_ENTRY_OFFSET(pmd_t * dir, unsigned long address)
{
return pmd_page(*dir) + ((address >> 13) & (PTRS_PER_PTE - 1));
}
extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address)
{
unsigned long page;
address = (address >> 13) & (PTRS_PER_PTE - 1);
if (pmd_none(*pmd)) {
pte_t *page = (pte_t *) get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
pmd_set(pmd, page);
return page + address;
}
pmd_set(pmd, BAD_PAGETABLE);
return NULL;
}
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("pte_alloc: bad pmd\n");
pmd_set(pmd, BAD_PAGETABLE);
return NULL;
}
return pmd_page(*pmd) + address;
}
extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
{
unsigned long page;
address = (address >> 23) & (PTRS_PER_PMD - 1);
if (pgd_none(*pgd)) {
pmd_t *page = (pmd_t *) get_free_page(GFP_KERNEL);
if (pgd_none(*pgd)) {
if (page) {
pgd_set(pgd, page);
return page + address;
}
pgd_set(pgd, BAD_PAGETABLE);
return NULL;
}
free_page((unsigned long) page);
}
if (pgd_bad(*pgd)) {
printk("pmd_alloc: bad pgd\n");
pgd_set(pgd, BAD_PAGETABLE);
return NULL;
}
return pgd_page(*pgd) + address;
}
#endif /* __KERNEL__ */
#endif /* _ALPHA_PAGE_H */
#ifndef __ALPHA_STRING_H
#define __ALPHA_STRING_H
extern void * __constant_c_memset(void *, unsigned long, long);
extern void * __memset(void *, char, size_t);
#define memset(s, c, count) \
(__builtin_constant_p(c) ? \
__constant_c_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
__memset((s),(c),(count)))
#endif
......@@ -18,12 +18,11 @@
#define BOOT_SIZE (16*1024)
#define KERNEL_START 0xfffffc0000300000
#define INIT_PCB 0xfffffc0000300000
#define SWAPPER_PGD 0xfffffc0000300000
#define INIT_STACK 0xfffffc0000302000
#define EMPTY_PGT 0xfffffc0000304000
#define EMPTY_PGE 0xfffffc0000308000
#define ZERO_PGE 0xfffffc000030A000
#define SWAPPER_PGD 0xfffffc000030C000
#define START_ADDR 0xfffffc0000310000
#define START_SIZE (1024*1024)
......
......@@ -67,6 +67,7 @@ enum nfs_stat {
NFSERR_NOENT = 2,
NFSERR_IO = 5,
NFSERR_NXIO = 6,
NFSERR_EAGAIN = 11,
NFSERR_ACCES = 13,
NFSERR_EXIST = 17,
NFSERR_NODEV = 19,
......
......@@ -20,7 +20,7 @@
#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
#define PER_BSD (0x0006)
#define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
/* Prototype for an lcall7 syscall handler. */
typedef asmlinkage void (*lcall7_func)(struct pt_regs *);
......
......@@ -526,7 +526,6 @@ Read XA Parameter:
*/
#define CMD1_RESET 0x0a
#define CMD2_RESET 0x01
#define CMDL_RESET 0x0a
#define CMDT_RESET 0xc0
#define CMD1_LOCK_CTL 0x0c
#define CMD2_LOCK_CTL 0x1e
......@@ -537,7 +536,6 @@ Read XA Parameter:
#define CMDL_TRAY_CTL 0x0d
#define CMDT_TRAY_CTL 0x1b
#define CMD1_MULTISESS 0x8d
#define CMD2_MULTISESS 0x43
#define CMDL_MULTISESS 0x8c
#define CMD1_SUBCHANINF 0x11
#define CMD2_SUBCHANINF 0x
......@@ -628,7 +626,7 @@ Read XA Parameter:
#define CMD0_DISKCODE 0x8a
#define CMD0_DISKINFO 0x8b
#define CMD1_DISKINFO 0x8b
#define CMD2_DISKINFO 0x
#define CMD2_DISKINFO 0x43
#define CMDL_DISKINFO 0x8b
#define CMDT_DISKINFO 0x43
#define CMD0_READTOC 0x8c
......
......@@ -68,7 +68,7 @@ __res; })
static char * number(char * str, long num, int base, int size, int precision
,int type)
{
char c,sign,tmp[36];
char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
int i;
......
......@@ -162,9 +162,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, s
icmph->type == ICMP_PARAMETERPROB)
return;
}
return;
}
icmp_statistics.IcmpOutMsgs++;
......
......@@ -63,6 +63,7 @@ static void igmp_start_timer(struct ip_mc_list *im)
return;
tv=random()%(10*HZ); /* Pick a number any number 8) */
im->timer.expires=tv;
im->tm_running=1;
add_timer(&im->timer);
}
......
......@@ -606,6 +606,7 @@ static int tcp_write_timeout(struct sock *sk)
if (sk->retransmits > TCP_RETR2)
{
sk->err = ETIMEDOUT;
sk->error_report(sk);
/*
* Time wait the socket
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment