A bit of reshuffling. Also some stricter prototyping.

This commit is contained in:
leo 1996-02-22 21:07:05 +00:00
parent f7dff866af
commit db7d722c4b
4 changed files with 218 additions and 176 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: atari5380.c,v 1.7 1996/02/14 08:09:47 leo Exp $ */
/* $NetBSD: atari5380.c,v 1.8 1996/02/22 21:07:05 leo Exp $ */
/*
* Copyright (c) 1995 Leo Weppelman.
@ -52,15 +52,6 @@
#include <machine/dma.h>
#endif
/*
* This is crap, but because the interrupts now run at MFP spl-level (6),
* splbio() is not enough at some places. The code should be checked to
* find out where splhigh() is needed and where splbio() should be used.
* Now that I use this interrupt sceme, the spl values are fake!
*/
#undef splbio()
#define splbio() splhigh()
/*
* Set the various driver options
*/
@ -85,6 +76,21 @@
#undef USE_PDMA /* Use special pdma-transfer function */
#define MIN_PHYS 65536 /*BARF!!!!*/
/*
* Include more driver definitions
*/
#include <atari/dev/ncr5380var.h>
/*
* This is crap, but because the interrupts now run at MFP spl-level (6),
* splbio() is not enough at some places. The code should be checked to
* find out where splhigh() is needed and where splbio() should be used.
* Now that I use this interrupt sceme, the spl values are fake!
*/
#undef splbio()
#define splbio() splhigh()
/*
* The atari specific driver options
*/
@ -199,8 +205,7 @@ struct dma_chain *dm;
#define tt_wrong_dma_range(reqp, dm) 0
#endif
static void scsi_tt_init(sc)
struct ncr_softc *sc;
static void scsi_tt_init(struct ncr_softc *sc)
{
/*
* Enable SCSI-related interrupts
@ -226,19 +231,17 @@ struct ncr_softc *sc;
#endif
}
static u_char get_tt_5380_reg(rnum)
u_short rnum;
static u_char get_tt_5380_reg(u_short rnum)
{
return(SCSI_5380->scsi_5380[(rnum << 1) | 1]);
}
static void set_tt_5380_reg(rnum, val)
u_short rnum, val;
static void set_tt_5380_reg(u_short rnum, u_short val)
{
SCSI_5380->scsi_5380[(rnum << 1) | 1] = val;
}
extern __inline__ void scsi_tt_ienable()
extern __inline__ void scsi_tt_ienable(void)
{
int sps = splbio();
MFP2->mf_ierb |= IB_SCDM;
@ -246,7 +249,7 @@ extern __inline__ void scsi_tt_ienable()
splx(sps);
}
extern __inline__ scsi_tt_idisable()
extern __inline__ void scsi_tt_idisable(void)
{
int sps = splbio();
MFP2->mf_ierb &= ~IB_SCDM;
@ -254,7 +257,7 @@ extern __inline__ scsi_tt_idisable()
splx(sps);
}
extern __inline__ scsi_tt_clr_ipend()
extern __inline__ void scsi_tt_clr_ipend(void)
{
int tmp;
@ -262,10 +265,7 @@ extern __inline__ scsi_tt_clr_ipend()
tmp = GET_TT_REG(NCR5380_IRCV);
}
static void scsi_tt_dmasetup(reqp, phase, mode)
SC_REQ *reqp;
u_int phase;
u_char mode;
static void scsi_tt_dmasetup(SC_REQ *reqp, u_int phase, u_char mode)
{
if (PH_IN(phase)) {
SCSI_DMA->s_dma_ctrl = SD_IN;
@ -288,8 +288,7 @@ u_char mode;
}
static int
tt_poll_edma(reqp)
SC_REQ *reqp;
tt_poll_edma(SC_REQ *reqp)
{
u_char dmstat, dmastat;
int timeout = 9000; /* XXX */
@ -331,9 +330,7 @@ SC_REQ *reqp;
* Convert physical DMA address to a virtual address.
*/
static u_char *
ptov(reqp, phaddr)
SC_REQ *reqp;
u_long *phaddr;
ptov(SC_REQ *reqp, u_long *phaddr)
{
struct dma_chain *dm;
u_char *vaddr;
@ -347,9 +344,7 @@ u_long *phaddr;
}
static int
tt_get_dma_result(reqp, bytes_left)
SC_REQ *reqp;
u_long *bytes_left;
tt_get_dma_result(SC_REQ *reqp, u_long *bytes_left)
{
int dmastat, dmstat;
u_char *byte_p;
@ -393,7 +388,7 @@ u_long *bytes_left;
if (((u_long)byte_p & 3) && PH_IN(reqp->phase)) {
u_char *p, *q;
p = ptov(reqp, (u_long)byte_p & ~3);
p = ptov(reqp, (u_long *)((u_long)byte_p & ~3));
q = (u_char*)&(SCSI_DMA->s_dma_res);
switch ((u_long)byte_p & 3) {
case 3: *p++ = *q++;
@ -777,11 +772,8 @@ u_long *bytes_left;
* Our autoconfig matching function
*/
static int
machine_match(pdp, cdp, auxp, cd)
struct device *pdp;
struct cfdata *cdp;
void *auxp;
struct cfdriver *cd;
machine_match(struct device *pdp, struct cfdata *cdp, void *auxp,
struct cfdriver *cd)
{
if (strcmp(auxp, cd->cd_name))
return(0);
@ -796,8 +788,7 @@ struct cfdriver *cd;
* the address space. Thus being DMA-able for all controllers.
*/
static u_char *
alloc_bounceb(len)
u_long len;
alloc_bounceb(u_long len)
{
u_long tmp;
@ -805,8 +796,7 @@ u_long len;
}
static void
free_bounceb(bounceb)
u_char *bounceb;
free_bounceb(u_char *bounceb)
{
free_stmem(bounceb);
}
@ -814,8 +804,8 @@ u_char *bounceb;
/*
* 5380 interrupt.
*/
scsi_ctrl(sr)
int sr; /* sr at time of interrupt */
void
scsi_ctrl(int sr)
{
if (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) {
scsi_idisable();
@ -831,8 +821,8 @@ int sr; /* sr at time of interrupt */
/*
* DMA controller interrupt
*/
scsi_dma(sr)
int sr; /* sr at time of interrupt */
void
scsi_dma(int sr)
{
SC_REQ *reqp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ncr5380.c,v 1.15 1996/02/10 22:10:45 leo Exp $ */
/* $NetBSD: ncr5380.c,v 1.16 1996/02/22 21:07:09 leo Exp $ */
/*
* Copyright (c) 1995 Leo Weppelman.
@ -30,38 +30,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef DBG_NOSTATIC
# define static
#endif
#ifdef DBG_SEL
# define DBG_SELPRINT(a,b) printf(a,b)
#else
# define DBG_SELPRINT(a,b)
#endif
#ifdef DBG_PIO
# define DBG_PIOPRINT(a,b,c) printf(a,b,c)
#else
# define DBG_PIOPRINT(a,b,c)
#endif
#ifdef DBG_INF
# define DBG_INFPRINT(a,b,c) a(b,c)
#else
# define DBG_INFPRINT(a,b,c)
#endif
#ifdef DBG_PID
/* static char *last_hit = NULL, *olast_hit = NULL; */
static char *last_hit[DBG_PID];
# define PID(a) \
{ int i; \
for (i=0; i< DBG_PID-1; i++) \
last_hit[i] = last_hit[i+1]; \
last_hit[DBG_PID-1] = a; } \
/* olast_hit = last_hit; last_hit = a; */
#else
# define PID(a)
#endif
/*
* Bit mask of targets you want debugging to be shown
*/
@ -104,7 +72,7 @@ static u_char busy;
static void ncr5380_minphys(struct buf *bp);
static int ncr5380_scsi_cmd(struct scsi_xfer *xs);
static int ncr5380_show_scsi_cmd(struct scsi_xfer *xs);
static void ncr5380_show_scsi_cmd(struct scsi_xfer *xs);
struct scsi_adapter ncr5380_switch = {
ncr5380_scsi_cmd, /* scsi_cmd() */
@ -330,7 +298,8 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs)
* We do not queue RESET commands
*/
if (flags & SCSI_RESET) {
scsi_reset(xs->sc_link->adapter_softc, "Got reset-command");
scsi_reset_verbose(xs->sc_link->adapter_softc,
"Got reset-command");
return (COMPLETE);
}
@ -469,7 +438,7 @@ ncr5380_minphys(struct buf *bp)
}
#undef MIN_PHYS
static int
static void
ncr5380_show_scsi_cmd(struct scsi_xfer *xs)
{
u_char *b = (u_char *) xs->cmd;
@ -744,8 +713,8 @@ struct ncr_softc *sc;
static int
scsi_select(reqp, code)
SC_REQ *reqp;
int code;
{
u_long timeout;
u_char tmp[1];
u_char phase;
u_long cnt;
@ -966,7 +935,7 @@ SC_REQ *reqp;
transfer_pio(&phase, &msg, &len, 0);
}
else scsi_reset(sc, "Connected to unidentified target");
else scsi_reset_verbose(sc, "Connected to unidentified target");
SET_5380_REG(NCR5380_ICOM, 0);
reqp->xs->error = code ? code : XS_DRIVER_STUFFUP;
@ -1030,7 +999,8 @@ struct ncr_softc *sc;
reqp->xs->error = XS_TIMEOUT;
finish_req(reqp);
if (!(tmp & SC_S_REQ))
scsi_reset(sc, "Timeout waiting for phase-change");
scsi_reset_verbose(sc,
"Timeout waiting for phase-change");
PID("info_transf2");
return (0);
}
@ -1261,7 +1231,7 @@ struct ncr_softc *sc;
u_char msg;
u_char target_mask;
int abort = 0;
SC_REQ *tmp, *prev;
SC_REQ *tmp = NULL, *prev;
PID("reselect1");
target_mask = GET_5380_REG(NCR5380_DATA) & ~SC_HOST_ID;
@ -1282,7 +1252,7 @@ struct ncr_softc *sc;
}
if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_SEL) {
/* Damn SEL isn't dropping */
scsi_reset(sc, "Target won't drop SEL during Reselect");
scsi_reset_verbose(sc, "Target won't drop SEL during Reselect");
return;
}
@ -1336,7 +1306,7 @@ struct ncr_softc *sc;
SET_5380_REG(NCR5380_ICOM, SC_A_ATN);
if (transfer_pio(&phase, &msg, &len, 0) || len)
scsi_reset(sc, "Failure to abort reselection");
scsi_reset_verbose(sc, "Failure to abort reselection");
}
else {
connected = tmp;
@ -1702,16 +1672,12 @@ u_long len;
return (-1);
}
static void
scsi_reset(sc, why)
struct ncr_softc *sc;
const char *why;
void
scsi_reset()
{
SC_REQ *tmp, *next;
int sps;
ncr_aprint(sc, "Resetting SCSI-bus (%s)\n", why);
PID("scsi_reset1");
sps = splbio();
SET_5380_REG(NCR5380_ICOM, SC_A_RST);
@ -1758,6 +1724,16 @@ const char *why;
delay(100000);
}
static void
scsi_reset_verbose(sc, why)
struct ncr_softc *sc;
const char *why;
{
ncr_aprint(sc, "Resetting SCSI-bus (%s)\n", why);
scsi_reset();
}
/*
* Check validity of the IRQ set by the 5380. If the interrupt is valid,
* the appropriate action is carried out (reselection or DMA ready) and
@ -1961,7 +1937,7 @@ show_request(reqp, qtxt)
SC_REQ *reqp;
char *qtxt;
{
printf("REQ-%s: %d %x[%d] cmd[0]=%x S=%x M=%x R=%x resid=%d dr_flag=%x %s\n",
printf("REQ-%s: %d %p[%d] cmd[0]=%x S=%x M=%x R=%x resid=%d dr_flag=%x %s\n",
qtxt, reqp->targ_id, reqp->xdata_ptr, reqp->xdata_len,
reqp->xcmd.opcode, reqp->status, reqp->message,
reqp->xs->error, reqp->xs->resid, reqp->dr_flag,
@ -1980,7 +1956,7 @@ show_signals(dmstat, idstat)
u_char dmstat, idstat;
{
u_short tmp, mask;
int i, j, need_pipe;
int j, need_pipe;
tmp = idstat | ((dmstat & 3) << 8);
printf("Bus signals (%02x/%02x): ", idstat, dmstat & 3);
@ -1996,6 +1972,7 @@ u_char dmstat, idstat;
printf("\n");
}
void
scsi_show()
{
SC_REQ *tmp;
@ -2003,6 +1980,8 @@ scsi_show()
u_char idstat, dmstat;
int i;
printf("scsi_show: main_running is%s running\n",
main_running ? "" : " not");
for (tmp = issue_q; tmp; tmp = tmp->next)
show_request(tmp, "ISSUED");
for (tmp = discon_q; tmp; tmp = tmp->next)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ncr5380reg.h,v 1.7 1996/02/10 22:10:48 leo Exp $ */
/* $NetBSD: ncr5380reg.h,v 1.8 1996/02/22 21:07:11 leo Exp $ */
/*
* Copyright (c) 1995 Leo Weppelman.
@ -156,104 +156,38 @@
#define INTR_RESEL 2
#define INTR_DMA 3
struct ncr_softc {
struct device sc_dev;
struct scsi_link sc_link;
/*
* Some (pre-SCSI2) devices don't support select with ATN.
* If the device responds to select with ATN by going into
* command phase (ignoring ATN), then we flag it in the
* following bitmask.
* We also keep track of which devices have been selected
* before. This allows us to not even try raising ATN if
* the target doesn't respond to it the first time.
*/
u_int8_t sc_noselatn;
u_int8_t sc_selected;
};
/*
* Max. number of dma-chains per request
*/
#define MAXDMAIO (MAXPHYS/NBPG + 1)
/*
* Some requests are not contiguous in physical memory. We need to break them
* up into contiguous parts for DMA.
*/
struct dma_chain {
u_int dm_count;
u_long dm_addr;
};
/*
* Define our issue, free and disconnect queue's.
*/
typedef struct req_q {
struct req_q *next; /* next in free, issue or discon queue */
struct req_q *link; /* next linked command to execute */
struct scsi_xfer *xs; /* request from high-level driver */
u_short dr_flag; /* driver state */
u_char phase; /* current SCSI phase */
u_char msgout; /* message to send when requested */
u_char targ_id; /* target for command */
u_char targ_lun; /* lun for command */
u_char status; /* returned status byte */
u_char message; /* returned message byte */
u_char *bounceb; /* allocated bounce buffer */
u_char *bouncerp; /* bounce read-pointer */
struct dma_chain dm_chain[MAXDMAIO];
struct dma_chain *dm_cur; /* current dma-request */
struct dma_chain *dm_last; /* last dma-request */
long xdata_len; /* length of transfer */
u_char *xdata_ptr; /* virtual address of transfer */
struct scsi_generic xcmd; /* command to execute */
} SC_REQ;
/*
* Values for dr_flag:
*/
#define DRIVER_IN_DMA 0x01 /* Non-polled DMA activated */
#define DRIVER_AUTOSEN 0x02 /* Doing automatic sense */
#define DRIVER_NOINT 0x04 /* We are booting: no interrupts */
#define DRIVER_DMAOK 0x08 /* DMA can be used on this request */
#define DRIVER_BOUNCING 0x10 /* Using the bounce buffer */
#define DRIVER_LINKCHK 0x20 /* Doing the linked command check */
/* XXX: Should go to ncr5380var.h */
static SC_REQ *issue_q = NULL; /* Commands waiting to be issued*/
static SC_REQ *discon_q = NULL; /* Commands disconnected */
static SC_REQ *connected = NULL; /* Command currently connected */
struct ncr_softc;
struct req_q;
/*
* Function decls:
*/
static int transfer_pio __P((u_char *, u_char *, u_long *, int));
static int wait_req_true __P((void));
static int wait_req_false __P((void));
static int scsi_select __P((SC_REQ *, int));
static int handle_message __P((SC_REQ *, u_int));
static int scsi_select __P((struct req_q *, int));
static int handle_message __P((struct req_q *, u_int));
static void ack_message __P((void));
static void nack_message __P((SC_REQ *, u_char));
static void nack_message __P((struct req_q *, u_char));
static int information_transfer __P((struct ncr_softc *));
static void reselect __P((struct ncr_softc *));
static int dma_ready __P((void));
static void transfer_dma __P((SC_REQ *, u_int, int));
static int check_autosense __P((SC_REQ *, int));
static void transfer_dma __P((struct req_q *, u_int, int));
static int check_autosense __P((struct req_q *, int));
static int reach_msg_out __P((struct ncr_softc *, u_long));
static int check_intr __P((struct ncr_softc *));
static void scsi_reset __P((struct ncr_softc *, const char *));
static int scsi_dmaok __P((SC_REQ *));
void scsi_reset __P((void));
static void scsi_reset_verbose __P((struct ncr_softc *, const char *));
static int scsi_dmaok __P((struct req_q *));
static void run_main __P((struct ncr_softc *));
static void scsi_main __P((struct ncr_softc *));
static void ncr_ctrl_intr __P((struct ncr_softc *));
static void ncr_dma_intr __P((struct ncr_softc *));
static void ncr_tprint __P((SC_REQ *, char *, ...));
static void ncr_tprint __P((struct req_q *, char *, ...));
static void ncr_aprint __P((struct ncr_softc *, char *, ...));
static void show_request __P((SC_REQ *, char *));
static void show_phase __P((SC_REQ *, int));
void scsi_show __P((void));
static void show_request __P((struct req_q *, char *));
/* static void show_phase __P((struct req_q *, int)); */
static void show_signals __P((u_char, u_char));
#endif /* _NCR5380REG_H */

View File

@ -0,0 +1,139 @@
/* $NetBSD: ncr5380var.h,v 1.1 1996/02/22 21:07:12 leo Exp $ */
/*
* Copyright (c) 1996 Leo Weppelman.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Leo Weppelman.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _NCR5380VAR_H
#define _NCR5380VAR_H
struct ncr_softc {
struct device sc_dev;
struct scsi_link sc_link;
/*
* Some (pre-SCSI2) devices don't support select with ATN.
* If the device responds to select with ATN by going into
* command phase (ignoring ATN), then we flag it in the
* following bitmask.
* We also keep track of which devices have been selected
* before. This allows us to not even try raising ATN if
* the target doesn't respond to it the first time.
*/
u_int8_t sc_noselatn;
u_int8_t sc_selected;
};
/*
* Max. number of dma-chains per request
*/
#define MAXDMAIO (MAXPHYS/NBPG + 1)
/*
* Some requests are not contiguous in physical memory. We need to break them
* up into contiguous parts for DMA.
*/
struct dma_chain {
u_int dm_count;
u_long dm_addr;
};
/*
* Define our issue, free and disconnect queue's.
*/
typedef struct req_q {
struct req_q *next; /* next in free, issue or discon queue */
struct req_q *link; /* next linked command to execute */
struct scsi_xfer *xs; /* request from high-level driver */
u_short dr_flag; /* driver state */
u_char phase; /* current SCSI phase */
u_char msgout; /* message to send when requested */
u_char targ_id; /* target for command */
u_char targ_lun; /* lun for command */
u_char status; /* returned status byte */
u_char message; /* returned message byte */
u_char *bounceb; /* allocated bounce buffer */
u_char *bouncerp; /* bounce read-pointer */
struct dma_chain dm_chain[MAXDMAIO];
struct dma_chain *dm_cur; /* current dma-request */
struct dma_chain *dm_last; /* last dma-request */
long xdata_len; /* length of transfer */
u_char *xdata_ptr; /* virtual address of transfer */
struct scsi_generic xcmd; /* command to execute */
} SC_REQ;
/*
* Values for dr_flag:
*/
#define DRIVER_IN_DMA 0x01 /* Non-polled DMA activated */
#define DRIVER_AUTOSEN 0x02 /* Doing automatic sense */
#define DRIVER_NOINT 0x04 /* We are booting: no interrupts */
#define DRIVER_DMAOK 0x08 /* DMA can be used on this request */
#define DRIVER_BOUNCING 0x10 /* Using the bounce buffer */
#define DRIVER_LINKCHK 0x20 /* Doing the linked command check */
static SC_REQ *issue_q = NULL; /* Commands waiting to be issued*/
static SC_REQ *discon_q = NULL; /* Commands disconnected */
static SC_REQ *connected = NULL; /* Command currently connected */
/*
* Various debug definitions
*/
#ifdef DBG_NOSTATIC
# define static
#endif
#ifdef DBG_SEL
# define DBG_SELPRINT(a,b) printf(a,b)
#else
# define DBG_SELPRINT(a,b)
#endif
#ifdef DBG_PIO
# define DBG_PIOPRINT(a,b,c) printf(a,b,c)
#else
# define DBG_PIOPRINT(a,b,c)
#endif
#ifdef DBG_INF
# define DBG_INFPRINT(a,b,c) a(b,c)
#else
# define DBG_INFPRINT(a,b,c)
#endif
#ifdef DBG_PID
/* static char *last_hit = NULL, *olast_hit = NULL; */
static char *last_hit[DBG_PID];
# define PID(a) \
{ int i; \
for (i=0; i< DBG_PID-1; i++) \
last_hit[i] = last_hit[i+1]; \
last_hit[DBG_PID-1] = a; } \
/* olast_hit = last_hit; last_hit = a; */
#else
# define PID(a)
#endif
#endif /* _NCR5380VAR_H */