patch-2.1.52 linux/drivers/scsi/ncr53c8xx.c
Next file: linux/drivers/scsi/ncr53c8xx.h
Previous file: linux/drivers/scsi/README.ncr53c8xx
Back to the patch index
Back to the overall index
- Lines: 1140
- Date:
Mon Aug 25 13:01:58 1997
- Orig file:
v2.1.51/linux/drivers/scsi/ncr53c8xx.c
- Orig date:
Thu Aug 14 20:49:16 1997
diff -u --recursive --new-file v2.1.51/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
@@ -60,11 +60,14 @@
** May 19 1997 by Richard Waltham <dormouse@farsrobt.demon.co.uk>:
** Support for NvRAM detection and reading.
**
+** August 18 1997 by Cort <cort@cs.nmt.edu>:
+** Support for Power/PC (Big Endian).
+**
*******************************************************************************
*/
/*
-** 26 July 1997, version 2.4
+** 23 August 1997, version 2.5a
**
** Supported SCSI-II features:
** Synchronous negotiation
@@ -306,6 +309,7 @@
** architecture.
*/
+#ifndef NCR_IOMAPPED
__initfunc(
static vm_offset_t remap_pci_mem(u_long base, u_long size)
)
@@ -332,6 +336,7 @@
vfree((void *) (vaddr & PAGE_MASK));
#endif
}
+#endif /* !NCR_IOMAPPED */
#else /* linux-1.2.13 */
@@ -657,6 +662,7 @@
int bus;
u_char device_fn;
u_int base;
+ u_int base_2;
u_int io_port;
int irq;
/* port and reg fields to use INB, OUTB macros */
@@ -743,79 +749,156 @@
/*==========================================================
**
-** Access to the controller chip.
-**
-** If NCR_IOMAPPED is defined, only IO are used by the driver.
+** Big/Little endian support.
**
**==========================================================
*/
/*
-** IO mapped only input / ouput
+** If the NCR uses big endian addressing mode over the
+** PCI, actual io register addresses for byte and word
+** accesses must be changed according to lane routing.
+** Btw, ncr_offb() and ncr_offw() macros only apply to
+** constants and so donnot generate bloated code.
*/
-#define IOM_INB(r) inb (np->port + offsetof(struct ncr_reg, r))
-#define IOM_INB_OFF(o) inb (np->port + (o))
-#define IOM_INW(r) inw (np->port + offsetof(struct ncr_reg, r))
-#define IOM_INL(r) inl (np->port + offsetof(struct ncr_reg, r))
-#define IOM_INL_OFF(o) inl (np->port + (o))
-
-#define IOM_OUTB(r, val) outb ((val), np->port+offsetof(struct ncr_reg,r))
-#define IOM_OUTW(r, val) outw ((val), np->port+offsetof(struct ncr_reg,r))
-#define IOM_OUTL(r, val) outl ((val), np->port+offsetof(struct ncr_reg,r))
-#define IOM_OUTL_OFF(o, val) outl ((val), np->port + (o))
+#if defined(SCSI_NCR_BIG_ENDIAN)
+
+#define ncr_offb(o) (((o)&~3)+((~((o)&3))&3))
+#define ncr_offw(o) (((o)&~3)+((~((o)&3))&2))
+
+#else
+
+#define ncr_offb(o) (o)
+#define ncr_offw(o) (o)
+
+#endif
/*
-** MEMORY mapped IO input / output
+** If the CPU and the NCR use same endian-ness adressing,
+** no byte reordering is needed for script patching.
+** Macro cpu_to_scr() is to be used for script patching.
+** Macro scr_to_cpu() is to be used for getting a DWORD
+** from the script.
*/
-#define MMIO_INB(r) readb(&np->reg->r)
-#define MMIO_INB_OFF(o) readb((char *)np->reg + (o))
-#define MMIO_INW(r) readw(&np->reg->r)
-#define MMIO_INL(r) readl(&np->reg->r)
-#define MMIO_INL_OFF(o) readl((char *)np->reg + (o))
-
-#define MMIO_OUTB(r, val) writeb((val), &np->reg->r)
-#define MMIO_OUTW(r, val) writew((val), &np->reg->r)
-#define MMIO_OUTL(r, val) writel((val), &np->reg->r)
-#define MMIO_OUTL_OFF(o, val) writel((val), (char *)np->reg + (o))
+#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw) cpu_to_le32(dw)
+#define scr_to_cpu(dw) le32_to_cpu(dw)
+
+#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw) cpu_to_be32(dw)
+#define scr_to_cpu(dw) be32_to_cpu(dw)
+
+#else
+
+#define cpu_to_scr(dw) (dw)
+#define scr_to_cpu(dw) (dw)
+
+#endif
+
+/*==========================================================
+**
+** Access to the controller chip.
+**
+** If NCR_IOMAPPED is defined, only IO are used by the driver.
+**
+**==========================================================
+*/
/*
-** IO mapped input / output
+** If the CPU and the NCR use same endian-ness adressing,
+** no byte reordering is needed for accessing chip io
+** registers. Functions suffixed by '_raw' are assumed
+** to access the chip over the PCI without doing byte
+** reordering. Functions suffixed by '_l2b' are
+** assumed to perform little-endian to big-endian byte
+** reordering, those suffixed by '_b2l' blah, blah,
+** blah, ...
*/
#if defined(NCR_IOMAPPED)
-#define INB(r) IOM_INB(r)
-#define INB_OFF(o) IOM_INB_OFF(o)
-#define INW(r) IOM_INW(r)
-#define INL(r) IOM_INL(r)
-#define INL_OFF(o) IOM_INL_OFF(o)
-
-#define OUTB(r, val) IOM_OUTB(r, val)
-#define OUTW(r, val) IOM_OUTW(r, val)
-#define OUTL(r, val) IOM_OUTL(r, val)
-#define OUTL_OFF(o, val) IOM_OUTL_OFF(o, val)
+/*
+** IO mapped only input / ouput
+*/
+
+#define INB_OFF(o) inb (np->port + ncr_offb(o))
+#define OUTB_OFF(o, val) outb ((val), np->port + ncr_offb(o))
+
+#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o) inw_l2b (np->port + ncr_offw(o))
+#define INL_OFF(o) inl_l2b (np->port + (o))
+
+#define OUTW_OFF(o, val) outw_b2l ((val), np->port + ncr_offw(o))
+#define OUTL_OFF(o, val) outl_b2l ((val), np->port + (o))
+
+#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o) inw_b2l (np->port + ncr_offw(o))
+#define INL_OFF(o) inl_b2l (np->port + (o))
+
+#define OUTW_OFF(o, val) outw_l2b ((val), np->port + ncr_offw(o))
+#define OUTL_OFF(o, val) outl_l2b ((val), np->port + (o))
+
+#else
+
+#define INW_OFF(o) inw_raw (np->port + ncr_offw(o))
+#define INL_OFF(o) inl_raw (np->port + (o))
+
+#define OUTW_OFF(o, val) outw_raw ((val), np->port + ncr_offw(o))
+#define OUTL_OFF(o, val) outl_raw ((val), np->port + (o))
+
+#endif /* ENDIANs */
+
+#else /* defined NCR_IOMAPPED */
/*
-** MEMORY mapped only input / output
+** MEMORY mapped IO input / output
*/
+#define INB_OFF(o) readb((char *)np->reg + ncr_offb(o))
+#define OUTB_OFF(o, val) writeb((val), (char *)np->reg + ncr_offb(o))
+
+#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o) readw_l2b((char *)np->reg + ncr_offw(o))
+#define INL_OFF(o) readl_l2b((char *)np->reg + (o))
+
+#define OUTW_OFF(o, val) writew_b2l((val), (char *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val) writel_b2l((val), (char *)np->reg + (o))
+
+#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o) readw_b2l((char *)np->reg + ncr_offw(o))
+#define INL_OFF(o) readl_b2l((char *)np->reg + (o))
+
+#define OUTW_OFF(o, val) writew_l2b((val), (char *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val) writel_l2b((val), (char *)np->reg + (o))
+
#else
-#define INB(r) MMIO_INB(r)
-#define INB_OFF(o) MMIO_INB_OFF(o)
-#define INW(r) MMIO_INW(r)
-#define INL(r) MMIO_INL(r)
-#define INL_OFF(o) MMIO_INL_OFF(o)
-
-#define OUTB(r, val) MMIO_OUTB(r, val)
-#define OUTW(r, val) MMIO_OUTW(r, val)
-#define OUTL(r, val) MMIO_OUTL(r, val)
-#define OUTL_OFF(o, val) MMIO_OUTL_OFF(o, val)
+#define INW_OFF(o) readw_raw((char *)np->reg + ncr_offw(o))
+#define INL_OFF(o) readl_raw((char *)np->reg + (o))
+
+#define OUTW_OFF(o, val) writew_raw((val), (char *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val) writel_raw((val), (char *)np->reg + (o))
#endif
+#endif /* defined NCR_IOMAPPED */
+
+#define INB(r) INB_OFF (offsetof(struct ncr_reg,r))
+#define INW(r) INW_OFF (offsetof(struct ncr_reg,r))
+#define INL(r) INL_OFF (offsetof(struct ncr_reg,r))
+
+#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val))
+
/*
** Set bit field ON, OFF
*/
@@ -827,6 +910,7 @@
#define OUTONL(r, m) OUTL(r, INL(r) | (m))
#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m))
+
/*==========================================================
**
** Command control block states.
@@ -1264,27 +1348,36 @@
** status fields.
*/
- u_char status[8];
+ u_char scr_st[4]; /* script status */
+ u_char status[4]; /* host status. Must be the last */
+ /* DWORD of the CCB header */
};
/*
** The status bytes are used by the host and the script processor.
**
-** The first four byte are copied to the scratchb register
+** The byte corresponding to the host_status must be stored in the
+** last DWORD of the CCB header since it is used for command
+** completion (ncr_wakeup()). Doing so, we are sure that the header
+** has been entirely copied back to the CCB when the host_status is
+** seen complete by the CPU.
+**
+** The last four bytes (status[4]) are copied to the scratchb register
** (declared as scr0..scr3 in ncr_reg.h) just after the select/reselect,
** and copied back just after disconnecting.
** Inside the script the XX_REG are used.
**
-** The last four bytes are used inside the script by "COPY" commands.
+** The first four bytes (scr_st[4]) are used inside the script by
+** "COPY" commands.
** Because source and destination must have the same alignment
-** in a longword, the fields HAVE to be at the choosen offsets.
-** xerr_st (4) 0 (0x34) scratcha
-** sync_st (5) 1 (0x05) sxfer
-** wide_st (7) 3 (0x03) scntl3
+** in a DWORD, the fields HAVE to be at the choosen offsets.
+** xerr_st 0 (0x34) scratcha
+** sync_st 1 (0x05) sxfer
+** wide_st 3 (0x03) scntl3
*/
/*
-** First four bytes (script)
+** Last four bytes (script)
*/
#define QU_REG scr0
#define HS_REG scr1
@@ -1293,7 +1386,7 @@
#define PS_REG scr3
/*
-** First four bytes (host)
+** Last four bytes (host)
*/
#define actualquirks phys.header.status[0]
#define host_status phys.header.status[1]
@@ -1301,15 +1394,15 @@
#define parity_status phys.header.status[3]
/*
-** Last four bytes (script)
+** First four bytes (script)
*/
-#define xerr_st header.status[4] /* MUST be ==0 mod 4 */
-#define sync_st header.status[5] /* MUST be ==1 mod 4 */
-#define nego_st header.status[6]
-#define wide_st header.status[7] /* MUST be ==3 mod 4 */
+#define xerr_st header.scr_st[0]
+#define sync_st header.scr_st[1]
+#define nego_st header.scr_st[2]
+#define wide_st header.scr_st[3]
/*
-** Last four bytes (host)
+** First four bytes (host)
*/
#define xerr_status phys.xerr_st
#define sync_status phys.sync_st
@@ -1677,9 +1770,11 @@
/*
** Timeout handler
*/
+#if 0
u_long heartbeat;
u_short ticks;
u_short latetime;
+#endif
u_long lasttime;
/*-----------------------------------------------
@@ -1771,7 +1866,7 @@
** of 825A, 875 and 895 chips.
*/
struct script {
- ncrcmd start [ 7];
+ ncrcmd start [ 4];
ncrcmd start0 [ 2];
ncrcmd start1 [ 3];
ncrcmd startpos [ 1];
@@ -1974,13 +2069,14 @@
static struct script script0 __initdata = {
/*--------------------------< START >-----------------------*/ {
+#if 0
/*
** Claim to be still alive ...
*/
SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)),
KVAR(SCRIPT_KVAR_JIFFIES),
NADDR (heartbeat),
-
+#endif
/*
** Make data structure address invalid.
** clear SIGP.
@@ -3593,7 +3689,8 @@
while (src < end) {
- *dst++ = opcode = *src++;
+ opcode = *src++;
+ *dst++ = cpu_to_scr(opcode);
/*
** If we forget to change the length
@@ -3638,7 +3735,7 @@
** the NO FLUSH bit if present.
*/
if ((opcode & SCR_NO_FLUSH) && !(np->features & FE_PFEN)) {
- dst[-1] = (opcode & ~SCR_NO_FLUSH);
+ dst[-1] = cpu_to_scr(opcode & ~SCR_NO_FLUSH);
++opchanged;
}
break;
@@ -3711,10 +3808,10 @@
break;
}
- *dst++ = new;
+ *dst++ = cpu_to_scr(new);
}
} else
- *dst++ = *src++;
+ *dst++ = cpu_to_scr(*src++);
};
if (bootverbose > 1 && opchanged)
@@ -3974,15 +4071,6 @@
np->maxsync = period > 2540 ? 254 : period / 10;
/*
- ** Get on-board RAM bus address when supported
- */
- if (np->features & FE_RAM) {
- OUTONB(nc_ctest2, 0x8);
- np->paddr2 = INL(nc_scr0);
- OUTOFFB(nc_ctest2, 0x8);
- }
-
- /*
** Prepare initial value of other IO registers
*/
#if defined SCSI_NCR_TRUST_BIOS_SETTING
@@ -4338,7 +4426,8 @@
** virtual and physical memory.
*/
- np->paddr = device->slot.base;
+ np->paddr = device->slot.base;
+ np->paddr2 = (np->features & FE_RAM)? device->slot.base_2 : 0;
#ifndef NCR_IOMAPPED
np->vaddr = remap_pci_mem((u_long) np->paddr, (u_long) 128);
@@ -4446,17 +4535,20 @@
*/
if (np->features & FE_LED0) {
- np->script0->reselect[0] = SCR_REG_REG(gpreg, SCR_OR, 0x01);
- np->script0->reselect1[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe);
- np->script0->reselect2[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe);
+ np->script0->reselect[0] =
+ cpu_to_scr(SCR_REG_REG(gpreg, SCR_OR, 0x01));
+ np->script0->reselect1[0] =
+ cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
+ np->script0->reselect2[0] =
+ cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
}
/*
** init data structure
*/
- np->jump_tcb.l_cmd = SCR_JUMP;
- np->jump_tcb.l_paddr = NCB_SCRIPTH_PHYS (np, abort);
+ np->jump_tcb.l_cmd = cpu_to_scr(SCR_JUMP);
+ np->jump_tcb.l_paddr = cpu_to_scr(NCB_SCRIPTH_PHYS (np, abort));
/*
** Reset chip.
@@ -4923,21 +5015,23 @@
u_long endp;
default:
case XferBoth:
- cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_io);
+ cp->phys.header.savep =
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, data_io));
cp->phys.header.goalp = cp->phys.header.savep;
break;
case XferIn:
endp = NCB_SCRIPT_PHYS (np, data_in) + MAX_SCATTER*16;
- cp->phys.header.goalp = endp + 8;
- cp->phys.header.savep = endp - segments*16;
+ cp->phys.header.goalp = cpu_to_scr(endp + 8);
+ cp->phys.header.savep = cpu_to_scr(endp - segments*16);
break;
case XferOut:
endp = NCB_SCRIPTH_PHYS (np, data_out) + MAX_SCATTER*16;
- cp->phys.header.goalp = endp + 8;
- cp->phys.header.savep = endp - segments*16;
+ cp->phys.header.goalp = cpu_to_scr(endp + 8);
+ cp->phys.header.savep = cpu_to_scr(endp - segments*16);
break;
case XferNone:
- cp->phys.header.savep = NCB_SCRIPT_PHYS (np, no_data);
+ cp->phys.header.savep =
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, no_data));
cp->phys.header.goalp = cp->phys.header.savep;
break;
}
@@ -4958,8 +5052,9 @@
/*
** Startqueue
*/
- cp->phys.header.launch.l_paddr = NCB_SCRIPT_PHYS (np, select);
- cp->phys.header.launch.l_cmd = SCR_JUMP;
+ cp->phys.header.launch.l_paddr =
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, select));
+ cp->phys.header.launch.l_cmd = cpu_to_scr(SCR_JUMP);
/*
** select
*/
@@ -4969,21 +5064,21 @@
/*
** message
*/
- cp->phys.smsg.addr = CCB_PHYS (cp, scsi_smsg);
- cp->phys.smsg.size = msglen;
+ cp->phys.smsg.addr = cpu_to_scr(CCB_PHYS (cp, scsi_smsg));
+ cp->phys.smsg.size = cpu_to_scr(msglen);
- cp->phys.smsg2.addr = CCB_PHYS (cp, scsi_smsg2);
- cp->phys.smsg2.size = msglen2;
+ cp->phys.smsg2.addr = cpu_to_scr(CCB_PHYS (cp, scsi_smsg2));
+ cp->phys.smsg2.size = cpu_to_scr(msglen2);
/*
** command
*/
- cp->phys.cmd.addr = vtophys (&cmd->cmnd[0]);
- cp->phys.cmd.size = cmd->cmd_len;
+ cp->phys.cmd.addr = cpu_to_scr(vtophys (&cmd->cmnd[0]));
+ cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len);
/*
** sense command
*/
- cp->phys.scmd.addr = CCB_PHYS (cp, sensecmd);
- cp->phys.scmd.size = 6;
+ cp->phys.scmd.addr = cpu_to_scr(CCB_PHYS (cp, sensecmd));
+ cp->phys.scmd.size = cpu_to_scr(6);
/*
** patch requested size into sense command
*/
@@ -4993,8 +5088,9 @@
/*
** sense data
*/
- cp->phys.sense.addr = vtophys (&cmd->sense_buffer[0]);
- cp->phys.sense.size = sizeof(cmd->sense_buffer);
+ cp->phys.sense.addr =
+ cpu_to_scr(vtophys (&cmd->sense_buffer[0]));
+ cp->phys.sense.size = cpu_to_scr(sizeof(cmd->sense_buffer));
/*
** status
*/
@@ -5019,8 +5115,10 @@
** reselect pattern and activate this job.
*/
- cp->jump_ccb.l_cmd = (SCR_JUMP ^ IFFALSE (DATA (cp->tag)));
- /* Compute a time limit bigger than the middle-level driver one */
+ cp->jump_ccb.l_cmd =
+ cpu_to_scr((SCR_JUMP ^ IFFALSE (DATA (cp->tag))));
+
+ /* Compute a time limit greater than the middle-level driver one */
if (cmd->timeout_per_command > 0)
cp->tlimit = jiffies + cmd->timeout_per_command + NCR_TIMEOUT_INCREASE;
else
@@ -5033,14 +5131,14 @@
qidx = np->squeueput + 1;
if (qidx >= MAX_START) qidx=0;
- np->squeue [qidx ] = NCB_SCRIPT_PHYS (np, idle);
- np->squeue [np->squeueput] = CCB_PHYS (cp, phys);
+ np->squeue [qidx ] = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
+ np->squeue [np->squeueput] = cpu_to_scr(CCB_PHYS (cp, phys));
np->squeueput = qidx;
if(DEBUG_FLAGS & DEBUG_QUEUE)
printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np),
np->squeueput,
- (unsigned)(np->script->startpos[0]-
+ (unsigned)(scr_to_cpu(np->script->startpos[0]) -
(NCB_SCRIPTH_PHYS (np, tryloop))));
/*
@@ -5246,10 +5344,12 @@
** this condition in order to complete the canceled command
** after the script skipped the ccb, if necessary.
*/
- cp->jump_ccb.l_cmd = (SCR_JUMP);
- if (cp->phys.header.launch.l_paddr == NCB_SCRIPT_PHYS (np, select)) {
+ cp->jump_ccb.l_cmd = cpu_to_scr(SCR_JUMP);
+ if (cp->phys.header.launch.l_paddr ==
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, select))) {
printf ("%s: abort ccb=%p (skip)\n", ncr_name (np), cp);
- cp->phys.header.launch.l_paddr = NCB_SCRIPT_PHYS (np, skip);
+ cp->phys.header.launch.l_paddr =
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, skip));
}
cp->tlimit = 0;
@@ -5440,12 +5540,12 @@
/*
** No Reselect anymore.
*/
- cp->jump_ccb.l_cmd = (SCR_JUMP);
+ cp->jump_ccb.l_cmd = cpu_to_scr(SCR_JUMP);
/*
** No starting.
*/
- cp->phys.header.launch.l_paddr= NCB_SCRIPT_PHYS (np, idle);
+ cp->phys.header.launch.l_paddr = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
/*
** timestamp
@@ -5797,14 +5897,14 @@
** Clear Start Queue
*/
for (i=0;i<MAX_START;i++)
- np -> squeue [i] = NCB_SCRIPT_PHYS (np, idle);
+ np -> squeue [i] = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
/*
** Start at first entry.
*/
np->squeueput = 0;
- np->script0->startpos[0] = NCB_SCRIPTH_PHYS (np, tryloop);
- np->script0->start0 [0] = SCR_INT ^ IFFALSE (0);
+ np->script0->startpos[0] = cpu_to_scr(NCB_SCRIPTH_PHYS (np, tryloop));
+ np->script0->start0 [0] = cpu_to_scr(SCR_INT ^ IFFALSE (0));
/*
** Wakeup all pending jobs.
@@ -5856,7 +5956,11 @@
if (np->vaddr2) {
if (bootverbose)
printf ("%s: copying script fragments into the on-board RAM ...\n", ncr_name(np));
- bcopy(np->script0, np->script, sizeof(struct script));
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
+ memcpy_toio(np->script, np->script0, sizeof(struct script));
+#else
+ memcpy(np->script, np->script0, sizeof(struct script));
+#endif
}
/*
@@ -6477,7 +6581,6 @@
{
u_long thistime = jiffies;
u_long count = 0;
- long signed t;
ccb_p cp;
u_long flags;
@@ -6551,10 +6654,12 @@
**
**----------------------------------------------------
*/
-
- t = (thistime - np->heartbeat) / HZ;
-
- if (t<2) np->latetime=0; else np->latetime++;
+#if 0
+ if (thistime < np->heartbeat + HZ + HZ)
+ np->latetime = 0;
+ else
+ np->latetime++;
+#endif
/*----------------------------------------------------
**
@@ -6597,7 +6702,7 @@
** still in start queue ?
*/
if (cp->phys.header.launch.l_paddr ==
- NCB_SCRIPT_PHYS (np, skip))
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, skip)))
continue;
/* fall through */
@@ -6746,15 +6851,18 @@
/*
** interrupt on the fly ?
- */
- while ((istat = INB (nc_istat)) & INTF) {
+ ** Since the global header may be copied back to a CCB
+ ** using a posted PCI memory write, the last operation on
+ ** the istat register is a READ in order to flush posted
+ ** PCI commands (Btw, the 'do' loop is probably useless).
+ */
+ istat = INB (nc_istat);
+ if (istat & INTF) {
+ do {
+ OUTB (nc_istat, (istat & SIGP) | INTF);
+ istat = INB (nc_istat);
+ } while (istat & INTF);
if (DEBUG_FLAGS & DEBUG_TINY) printf ("F ");
-#ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
- if (np->stalling)
- OUTB (nc_istat, INTF);
- else
-#endif
- OUTB (nc_istat, (istat & SIGP) | INTF);
np->profile.num_fly++;
ncr_wakeup (np, 0);
};
@@ -6944,7 +7052,7 @@
/* assert ((diff <= MAX_START * 20) && !(diff % 20));*/
if ((diff <= MAX_START * 20) && !(diff % 20)) {
- np->script->startpos[0] = scratcha;
+ np->script->startpos[0] = cpu_to_scr(scratcha);
OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
return;
};
@@ -7136,20 +7244,20 @@
** get old startaddress and old length.
*/
- oadr = vdsp[1];
+ oadr = scr_to_cpu(vdsp[1]);
if (cmd & 0x10) { /* Table indirect */
tblp = (u_int32 *) ((char*) &cp->phys + oadr);
- olen = tblp[0];
- oadr = tblp[1];
+ olen = scr_to_cpu(tblp[0]);
+ oadr = scr_to_cpu(tblp[1]);
} else {
tblp = (u_int32 *) 0;
- olen = vdsp[0] & 0xffffff;
+ olen = scr_to_cpu(vdsp[0]) & 0xffffff;
};
if (DEBUG_FLAGS & DEBUG_PHASE) {
printf ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
- (unsigned) (vdsp[0] >> 24),
+ (unsigned) (scr_to_cpu(vdsp[0]) >> 24),
tblp,
(unsigned) olen,
(unsigned) oadr);
@@ -7159,10 +7267,10 @@
** check cmd against assumed interrupted script command.
*/
- if (cmd != (vdsp[0] >> 24)) {
+ if (cmd != (scr_to_cpu(vdsp[0]) >> 24)) {
PRINT_ADDR(cp->cmd);
printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
- (unsigned)cmd, (unsigned)vdsp[0] >> 24);
+ (unsigned)cmd, (unsigned)scr_to_cpu(vdsp[0]) >> 24);
return;
}
@@ -7194,25 +7302,25 @@
*/
newcmd = cp->patch;
- if (cp->phys.header.savep == vtophys (newcmd)) newcmd+=4;
+ if (cp->phys.header.savep == cpu_to_scr(vtophys (newcmd))) newcmd+=4;
/*
** fillin the commands
*/
- newcmd[0] = ((cmd & 0x0f) << 24) | rest;
- newcmd[1] = oadr + olen - rest;
- newcmd[2] = SCR_JUMP;
- newcmd[3] = nxtdsp;
+ newcmd[0] = cpu_to_scr(((cmd & 0x0f) << 24) | rest);
+ newcmd[1] = cpu_to_scr(oadr + olen - rest);
+ newcmd[2] = cpu_to_scr(SCR_JUMP);
+ newcmd[3] = cpu_to_scr(nxtdsp);
if (DEBUG_FLAGS & DEBUG_PHASE) {
PRINT_ADDR(cp->cmd);
printf ("newcmd[%d] %x %x %x %x.\n",
(int) (newcmd - cp->patch),
- (unsigned)newcmd[0],
- (unsigned)newcmd[1],
- (unsigned)newcmd[2],
- (unsigned)newcmd[3]);
+ (unsigned)scr_to_cpu(newcmd[0]),
+ (unsigned)scr_to_cpu(newcmd[1]),
+ (unsigned)scr_to_cpu(newcmd[2]),
+ (unsigned)scr_to_cpu(newcmd[3]));
}
/*
** fake the return address (to the patch).
@@ -7299,20 +7407,23 @@
*/
if (num == SIR_DATA_IO_IS_OUT) {
endp = NCB_SCRIPTH_PHYS (np, data_out) + MAX_SCATTER*16;
- cp->phys.header.goalp = endp + 8;
- cp->phys.header.savep = endp - cp->segments*16;
+ cp->phys.header.goalp = cpu_to_scr(endp + 8);
+ cp->phys.header.savep =
+ cpu_to_scr(endp - cp->segments*16);
} else {
endp = NCB_SCRIPT_PHYS (np, data_in) + MAX_SCATTER*16;
- cp->phys.header.goalp = endp + 8;
- cp->phys.header.savep = endp - cp->segments*16;
+ cp->phys.header.goalp = cpu_to_scr(endp + 8);
+ cp->phys.header.savep =
+ cpu_to_scr(endp - cp->segments*16);
}
cp->phys.header.lastp = cp->phys.header.savep;
np->header.savep = cp->phys.header.savep;
np->header.goalp = cp->phys.header.goalp;
np->header.lastp = cp->phys.header.lastp;
- OUTL (nc_temp, np->header.savep);
- OUTL (nc_dsp, np->header.savep);
+
+ OUTL (nc_temp, scr_to_cpu(np->header.savep));
+ OUTL (nc_dsp, scr_to_cpu(np->header.savep));
return;
/* break; */
@@ -7359,7 +7470,7 @@
** no job, resume normal processing
*/
if (DEBUG_FLAGS & DEBUG_RESTART) printf (" -- remove trap\n");
- np->script->start0[0] = SCR_INT ^ IFFALSE (0);
+ np->script->start0[0] = cpu_to_scr(SCR_INT ^ IFFALSE (0));
break;
case SIR_SENSE_FAILED:
@@ -7385,7 +7496,7 @@
/*
** And patch code to restart it.
*/
- np->script->start0[0] = SCR_INT;
+ np->script->start0[0] = cpu_to_scr(SCR_INT);
break;
/*-----------------------------------------------------------------------------
@@ -7742,7 +7853,7 @@
PRINT_ADDR(cp->cmd);
printf ("M_REJECT received (%x:%x).\n",
- (unsigned)np->lastmsg, np->msgout[0]);
+ (unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]);
break;
case SIR_REJECT_SENT:
@@ -7792,8 +7903,8 @@
printf ("M_DISCONNECT received, but datapointer not saved: "
"data=%x save=%x goal=%x.\n",
(unsigned) INL (nc_temp),
- (unsigned) np->header.savep,
- (unsigned) np->header.goalp);
+ (unsigned) scr_to_cpu(np->header.savep),
+ (unsigned) scr_to_cpu(np->header.goalp));
break;
#if 0 /* This stuff does not work */
@@ -7824,7 +7935,7 @@
PRINT_ADDR(cp->cmd);
printf ("queue full.\n");
- np->script->start1[0] = SCR_INT;
+ np->script->start1[0] = cpu_to_scr(SCR_INT);
/*
** Try to disable tagged transfers.
@@ -7872,7 +7983,7 @@
*/
printf ("%s: queue empty.\n", ncr_name (np));
- np->script->start1[0] = SCR_INT ^ IFFALSE (0);
+ np->script->start1[0] = cpu_to_scr(SCR_INT ^ IFFALSE (0));
break;
#endif /* This stuff does not work */
};
@@ -8011,33 +8122,37 @@
tp=&np->target[target];
if (!tp->jump_tcb.l_cmd) {
-
/*
** initialize it.
*/
- tp->jump_tcb.l_cmd = (SCR_JUMP^IFFALSE (DATA (0x80 + target)));
+ tp->jump_tcb.l_cmd =
+ cpu_to_scr((SCR_JUMP^IFFALSE (DATA (0x80 + target))));
tp->jump_tcb.l_paddr = np->jump_tcb.l_paddr;
- tp->getscr[0] =
- (np->features & FE_PFEN)? SCR_COPY(1) : SCR_COPY_F(1);
- tp->getscr[1] = vtophys (&tp->sval);
- tp->getscr[2] = np->paddr + offsetof (struct ncr_reg, nc_sxfer);
- tp->getscr[3] =
- (np->features & FE_PFEN)? SCR_COPY(1) : SCR_COPY_F(1);
- tp->getscr[4] = vtophys (&tp->wval);
- tp->getscr[5] = np->paddr + offsetof (struct ncr_reg, nc_scntl3);
+ tp->getscr[0] = (np->features & FE_PFEN) ?
+ cpu_to_scr(SCR_COPY(1)):cpu_to_scr(SCR_COPY_F(1));
+ tp->getscr[1] = cpu_to_scr(vtophys (&tp->sval));
+ tp->getscr[2] =
+ cpu_to_scr(np->paddr + offsetof (struct ncr_reg, nc_sxfer));
+
+ tp->getscr[3] = (np->features & FE_PFEN) ?
+ cpu_to_scr(SCR_COPY(1)):cpu_to_scr(SCR_COPY_F(1));
+ tp->getscr[4] = cpu_to_scr(vtophys (&tp->wval));
+ tp->getscr[5] =
+ cpu_to_scr(np->paddr + offsetof (struct ncr_reg, nc_scntl3));
assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
offsetof(struct tcb , sval )) &3) == 0);
assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
offsetof(struct tcb , wval )) &3) == 0);
- tp->call_lun.l_cmd = (SCR_CALL);
- tp->call_lun.l_paddr = NCB_SCRIPT_PHYS (np, resel_lun);
-
- tp->jump_lcb.l_cmd = (SCR_JUMP);
- tp->jump_lcb.l_paddr = NCB_SCRIPTH_PHYS (np, abort);
- np->jump_tcb.l_paddr = vtophys (&tp->jump_tcb);
+ tp->call_lun.l_cmd = cpu_to_scr(SCR_CALL);
+ tp->call_lun.l_paddr =
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, resel_lun));
+
+ tp->jump_lcb.l_cmd = cpu_to_scr(SCR_JUMP);
+ tp->jump_lcb.l_paddr = cpu_to_scr(NCB_SCRIPTH_PHYS (np, abort));
+ np->jump_tcb.l_paddr = cpu_to_scr(vtophys (&tp->jump_tcb));
}
/*
@@ -8060,14 +8175,17 @@
** Initialize it
*/
bzero (lp, sizeof (*lp));
- lp->jump_lcb.l_cmd = (SCR_JUMP ^ IFFALSE (DATA (lun)));
+ lp->jump_lcb.l_cmd =
+ cpu_to_scr(SCR_JUMP ^ IFFALSE (DATA (lun)));
lp->jump_lcb.l_paddr = tp->jump_lcb.l_paddr;
- lp->call_tag.l_cmd = (SCR_CALL);
- lp->call_tag.l_paddr = NCB_SCRIPT_PHYS (np, resel_tag);
-
- lp->jump_ccb.l_cmd = (SCR_JUMP);
- lp->jump_ccb.l_paddr = NCB_SCRIPTH_PHYS (np, aborttag);
+ lp->call_tag.l_cmd = cpu_to_scr(SCR_CALL);
+ lp->call_tag.l_paddr =
+ cpu_to_scr(NCB_SCRIPT_PHYS (np, resel_tag));
+
+ lp->jump_ccb.l_cmd = cpu_to_scr(SCR_JUMP);
+ lp->jump_ccb.l_paddr =
+ cpu_to_scr(NCB_SCRIPTH_PHYS (np, aborttag));
lp->actlink = 1;
@@ -8076,7 +8194,7 @@
/*
** Chain into LUN list
*/
- tp->jump_lcb.l_paddr = vtophys (&lp->jump_lcb);
+ tp->jump_lcb.l_paddr = cpu_to_scr(vtophys (&lp->jump_lcb));
tp->lp[lun] = lp;
ncr_setmaxtags (np, tp, driver_setup.default_tags);
@@ -8128,11 +8246,11 @@
/*
** Chain into reselect list
*/
- cp->jump_ccb.l_cmd = SCR_JUMP;
+ cp->jump_ccb.l_cmd = cpu_to_scr(SCR_JUMP);
cp->jump_ccb.l_paddr = lp->jump_ccb.l_paddr;
- lp->jump_ccb.l_paddr = CCB_PHYS (cp, jump_ccb);
- cp->call_tmp.l_cmd = SCR_CALL;
- cp->call_tmp.l_paddr = NCB_SCRIPT_PHYS (np, resel_tmp);
+ lp->jump_ccb.l_paddr = cpu_to_scr(CCB_PHYS (cp, jump_ccb));
+ cp->call_tmp.l_cmd = cpu_to_scr(SCR_CALL);
+ cp->call_tmp.l_paddr = cpu_to_scr(NCB_SCRIPT_PHYS (np, resel_tmp));
/*
** Chain into wakeup list
@@ -8245,9 +8363,9 @@
if (!use_sg) {
if (cmd->request_bufflen) {
data = &data[MAX_SCATTER - 1];
- data[0].addr = vtophys(cmd->request_buffer);
- data[0].size = cmd->request_bufflen;
- cp->data_len = data[0].size;
+ data[0].addr = cpu_to_scr(vtophys(cmd->request_buffer));
+ data[0].size = cpu_to_scr(cmd->request_bufflen);
+ cp->data_len = cmd->request_bufflen;
segment = 1;
}
}
@@ -8256,9 +8374,11 @@
data = &data[MAX_SCATTER - use_sg];
while (segment < use_sg) {
- data[segment].addr = vtophys(scatter[segment].address);
- data[segment].size = scatter[segment].length;
- cp->data_len += data[segment].size;
+ data[segment].addr =
+ cpu_to_scr(vtophys(scatter[segment].address));
+ data[segment].size =
+ cpu_to_scr(scatter[segment].length);
+ cp->data_len += scatter[segment].length;
++segment;
}
}
@@ -8328,7 +8448,7 @@
/*
** Set memory and register.
*/
- np->ncr_cache = host_wr;
+ np->ncr_cache = cpu_to_scr(host_wr);
OUTL (nc_temp, ncr_wr);
/*
** Start script (exchange values)
@@ -8347,7 +8467,7 @@
/*
** Read memory and register.
*/
- host_rd = np->ncr_cache;
+ host_rd = scr_to_cpu(np->ncr_cache);
ncr_rd = INL (nc_scratcha);
ncr_bk = INL (nc_temp);
/*
@@ -8791,7 +8911,7 @@
else if (!strncmp(cur, "safe:", 5) && val)
memcpy(&driver_setup, &driver_safe_setup, sizeof(driver_setup));
else
- printf("ncr53c8xx_setup: unexpected boot option '%.*s' ignored\n", pc-cur+1, cur);
+ printf("ncr53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
if ((cur = strchr(cur, ',')) != NULL)
++cur;
@@ -9068,11 +9188,11 @@
uchar cache_line_size, latency_timer;
uchar irq, revision;
#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
- uint base, io_port;
+ uint base, base_2, io_port;
#else
- ulong base, io_port;
+ ulong base, base_2;
#endif
- int i, error;
+ int i;
#ifdef SCSI_NCR_NVRAM_SUPPORT
ncr_nvram *nvram = device->nvram;
@@ -9082,20 +9202,32 @@
printk(KERN_INFO "ncr53c8xx: at PCI bus %d, device %d, function %d\n",
bus, (int) (device_fn & 0xf8) >> 3, (int) device_fn & 7);
/*
- * Read info from the PCI config space
+ * Read info from the PCI config space.
+ * pcibios_read_config_xxx() functions are assumed to be used for
+ * successfully detected PCI devices.
+ * Expecting error conditions from them is just paranoia,
+ * thus void cast.
*/
- if (
- (error=pcibios_read_config_word(bus, device_fn, PCI_VENDOR_ID, &vendor_id)) ||
- (error=pcibios_read_config_word(bus, device_fn, PCI_DEVICE_ID, &device_id)) ||
- (error=pcibios_read_config_word( bus, device_fn, PCI_COMMAND, &command)) ||
- (error=pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_0,&io_port)) ||
- (error=pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_1, &base)) ||
- (error=pcibios_read_config_byte(bus, device_fn, PCI_CLASS_REVISION,&revision)) ||
- (error=pcibios_read_config_byte(bus, device_fn, PCI_INTERRUPT_LINE, &irq)) ||
- (error=pcibios_read_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, &cache_line_size)) ||
- (error=pcibios_read_config_byte(bus, device_fn, PCI_LATENCY_TIMER, &latency_timer))
- )
- goto err_pcibios;
+ (void) pcibios_read_config_word(bus, device_fn,
+ PCI_VENDOR_ID, &vendor_id);
+ (void) pcibios_read_config_word(bus, device_fn,
+ PCI_DEVICE_ID, &device_id);
+ (void) pcibios_read_config_word(bus, device_fn,
+ PCI_COMMAND, &command);
+ (void) pcibios_read_config_dword(bus, device_fn,
+ PCI_BASE_ADDRESS_0, &io_port);
+ (void) pcibios_read_config_dword(bus, device_fn,
+ PCI_BASE_ADDRESS_1, &base);
+ (void) pcibios_read_config_dword(bus, device_fn,
+ PCI_BASE_ADDRESS_2, &base_2);
+ (void) pcibios_read_config_byte(bus, device_fn,
+ PCI_CLASS_REVISION,&revision);
+ (void) pcibios_read_config_byte(bus, device_fn,
+ PCI_INTERRUPT_LINE, &irq);
+ (void) pcibios_read_config_byte(bus, device_fn,
+ PCI_CACHE_LINE_SIZE, &cache_line_size);
+ (void) pcibios_read_config_byte(bus, device_fn,
+ PCI_LATENCY_TIMER, &latency_timer);
/*
* Check if the chip is supported
@@ -9148,6 +9280,8 @@
return -1;
}
+ base_2 &= PCI_BASE_ADDRESS_MEM_MASK;
+
if (io_port && check_region (io_port, 128)) {
printk("ncr53c8xx: IO region 0x%x to 0x%x is in use\n",
(int) io_port, (int) (io_port + 127));
@@ -9188,9 +9322,8 @@
case 5: cache_line_size = 8; break;
}
if (cache_line_size)
- error = pcibios_write_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, cache_line_size);
- if (error)
- goto err_pcibios;
+ (void) pcibios_write_config_byte(bus, device_fn,
+ PCI_CACHE_LINE_SIZE, cache_line_size);
if (initverbose)
printk("ncr53c8xx: setting PCI_CACHE_LINE_SIZE to %d (fix-up).\n", cache_line_size);
}
@@ -9198,9 +9331,8 @@
if ((driver_setup.pci_fix_up & 2) && cache_line_size &&
(chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) {
command |= PCI_COMMAND_INVALIDATE;
- error=pcibios_write_config_word(bus, device_fn, PCI_COMMAND, command);
- if (error)
- goto err_pcibios;
+ (void) pcibios_write_config_word(bus, device_fn,
+ PCI_COMMAND, command);
if (initverbose)
printk("ncr53c8xx: setting PCI_COMMAND_INVALIDATE bit (fix-up).\n");
}
@@ -9242,10 +9374,8 @@
latency_timer = lt;
if (initverbose)
printk("ncr53c8xx: setting PCI_LATENCY_TIMER to %d bus clocks (fix-up).\n", latency_timer);
- error = pcibios_write_config_byte(bus, device_fn,
+ (void) pcibios_write_config_byte(bus, device_fn,
PCI_LATENCY_TIMER, latency_timer);
- if (error)
- goto err_pcibios;
}
}
@@ -9271,6 +9401,7 @@
device->slot.bus = bus;
device->slot.device_fn = device_fn;
device->slot.base = base;
+ device->slot.base_2 = base_2;
device->slot.io_port = io_port;
device->slot.irq = irq;
device->attached = 0;
@@ -9321,11 +9452,6 @@
#endif /* SCSI_NCR_NVRAM_SUPPORT */
return 0;
-
-err_pcibios:
- printk("ncr53c8xx: error %s reading configuration space\n",
- pcibios_strerror(error));
- return -1;
}
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov