Get in sync with the mac68k version of the 5380 driver. Also increase
the maximum values of wait_req_xx() functions so some old (slow) scsi-1 drives will work.
This commit is contained in:
parent
b0db2f6250
commit
b4ca145026
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# $NetBSD: GENERIC,v 1.14 1996/05/14 10:21:48 leo Exp $
|
||||
# $NetBSD: GENERIC,v 1.15 1996/05/15 09:21:29 leo Exp $
|
||||
#
|
||||
# Generic atari
|
||||
#
|
||||
|
@ -104,6 +104,9 @@ options RAMDISK_HOOKS # Boot RAM-disk
|
|||
options DISKLABEL_NBDA # NetBSD disklabels (required)
|
||||
options DISKLABEL_AHDI # NetBSD/AHDI disklabels
|
||||
|
||||
# Try linked commands on all targets
|
||||
options TRY_SCSI_LINKED_COMMANDS=0x7f
|
||||
|
||||
#
|
||||
# Build one kernel that can boot from any disk.
|
||||
#
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ncr5380.c,v 1.19 1996/04/26 06:50:16 leo Exp $ */
|
||||
/* $NetBSD: ncr5380.c,v 1.20 1996/05/15 09:21:51 leo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Leo Weppelman.
|
||||
|
@ -46,10 +46,17 @@ u_char ncr5380_no_parchk = 0xff;
|
|||
|
||||
/*
|
||||
* Bit masks of targets that accept linked commands, and those
|
||||
* that we've already checked out
|
||||
* that we've already checked out. Some devices will report
|
||||
* that they support linked commands when they have problems with
|
||||
* them. By default, don't try them on any devices. Allow an
|
||||
* option to override.
|
||||
*/
|
||||
#ifdef TRY_SCSI_LINKED_COMMANDS
|
||||
u_char ncr_test_link = ((~TRY_SCSI_LINKED_COMMANDS) & 0x7f);
|
||||
#else
|
||||
u_char ncr_test_link = 0x7f;
|
||||
#endif
|
||||
u_char ncr_will_link = 0x00;
|
||||
u_char ncr_test_link = 0x00;
|
||||
|
||||
#endif /* AUTO_SENSE */
|
||||
|
||||
|
@ -70,9 +77,9 @@ static volatile int main_running = 0;
|
|||
*/
|
||||
static u_char busy;
|
||||
|
||||
static void ncr5380_minphys(struct buf *bp);
|
||||
static int ncr5380_scsi_cmd(struct scsi_xfer *xs);
|
||||
static void ncr5380_show_scsi_cmd(struct scsi_xfer *xs);
|
||||
static void ncr5380_minphys __P((struct buf *bp));
|
||||
static int ncr5380_scsi_cmd __P((struct scsi_xfer *xs));
|
||||
static void ncr5380_show_scsi_cmd __P((struct scsi_xfer *xs));
|
||||
|
||||
struct scsi_adapter ncr5380_switch = {
|
||||
ncr5380_scsi_cmd, /* scsi_cmd() */
|
||||
|
@ -125,7 +132,7 @@ u_char opcode;
|
|||
*/
|
||||
extern __inline__ int wait_req_true(void)
|
||||
{
|
||||
int timeout = 25000;
|
||||
int timeout = 250000;
|
||||
|
||||
while (!(GET_5380_REG(NCR5380_IDSTAT) & SC_S_REQ) && --timeout)
|
||||
delay(1);
|
||||
|
@ -138,7 +145,7 @@ extern __inline__ int wait_req_true(void)
|
|||
*/
|
||||
extern __inline__ int wait_req_false(void)
|
||||
{
|
||||
int timeout = 25000;
|
||||
int timeout = 250000;
|
||||
|
||||
while ((GET_5380_REG(NCR5380_IDSTAT) & SC_S_REQ) && --timeout)
|
||||
delay(1);
|
||||
|
@ -326,6 +333,7 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs)
|
|||
reqp->phase = NR_PHASE;
|
||||
reqp->msgout = MSG_NOOP;
|
||||
reqp->status = SCSGOOD;
|
||||
reqp->message = 0xff;
|
||||
reqp->link = NULL;
|
||||
reqp->xs = xs;
|
||||
reqp->targ_id = xs->sc_link->target;
|
||||
|
@ -677,7 +685,6 @@ ncr_ctrl_intr(sc)
|
|||
struct ncr_softc *sc;
|
||||
{
|
||||
int itype;
|
||||
int dma_done;
|
||||
|
||||
while (scsi_ipending()) {
|
||||
scsi_idisable();
|
||||
|
@ -686,6 +693,7 @@ struct ncr_softc *sc;
|
|||
reselect(sc);
|
||||
else {
|
||||
#ifdef REAL_DMA
|
||||
int dma_done;
|
||||
if (!(dma_done = dma_ready())) {
|
||||
transfer_dma(connected, connected->phase, 0);
|
||||
return;
|
||||
|
@ -1239,10 +1247,19 @@ u_int msg;
|
|||
PID("hmessage9");
|
||||
return (-1);
|
||||
default:
|
||||
ncr_tprint(reqp, "Unknown message %x\n", msg);
|
||||
if ((msg & 0x80) && !(msg & 0x18)) { /* IDENTIFY */
|
||||
PID("hmessage10");
|
||||
ack_message();
|
||||
return (0);
|
||||
} else {
|
||||
ncr_tprint(reqp,
|
||||
"Unknown message %x. Rejecting.\n",
|
||||
msg);
|
||||
nack_message(reqp, MSG_MESSAGE_REJECT);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
PID("hmessage10");
|
||||
PID("hmessage11");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -1260,7 +1277,7 @@ struct ncr_softc *sc;
|
|||
u_char msg;
|
||||
u_char target_mask;
|
||||
int abort = 0;
|
||||
SC_REQ *tmp = NULL, *prev;
|
||||
SC_REQ *tmp, *prev;
|
||||
|
||||
PID("reselect1");
|
||||
target_mask = GET_5380_REG(NCR5380_DATA) & ~SC_HOST_ID;
|
||||
|
@ -1308,6 +1325,7 @@ struct ncr_softc *sc;
|
|||
if (len || !MSG_ISIDENTIFY(msg)) {
|
||||
ncr_aprint(sc, "Expecting IDENTIFY, got 0x%x\n", msg);
|
||||
abort = 1;
|
||||
tmp = NULL;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ncr5380reg.h,v 1.9 1996/03/08 21:55:00 leo Exp $ */
|
||||
/* $NetBSD: ncr5380reg.h,v 1.10 1996/05/15 09:21:53 leo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Leo Weppelman.
|
||||
|
@ -156,41 +156,111 @@
|
|||
#define INTR_RESEL 2
|
||||
#define INTR_DMA 3
|
||||
|
||||
struct ncr_softc;
|
||||
struct req_q;
|
||||
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 */
|
||||
|
||||
/*
|
||||
* 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((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((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((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_autosense __P((SC_REQ *, int));
|
||||
static int check_intr __P((struct ncr_softc *));
|
||||
void finish_req __P((struct req_q *));
|
||||
int command_size __P((u_char));
|
||||
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 int command_size __P((u_char));
|
||||
static int dma_ready __P((void));
|
||||
static void finish_req __P((SC_REQ *));
|
||||
static int handle_message __P((SC_REQ *, u_int));
|
||||
static int information_transfer __P((struct ncr_softc *));
|
||||
static void nack_message __P((SC_REQ *, u_char));
|
||||
static void ncr_aprint __P((struct ncr_softc *, char *, ...));
|
||||
static void ncr_ctrl_intr __P((struct ncr_softc *));
|
||||
static void ncr_dma_intr __P((struct ncr_softc *));
|
||||
static void ncr_tprint __P((struct req_q *, char *, ...));
|
||||
static void ncr_aprint __P((struct ncr_softc *, char *, ...));
|
||||
|
||||
void scsi_show __P((void));
|
||||
static void show_request __P((struct req_q *, char *));
|
||||
static void ncr_tprint __P((SC_REQ *, char *, ...));
|
||||
static int reach_msg_out __P((struct ncr_softc *, u_long));
|
||||
static void reselect __P((struct ncr_softc *));
|
||||
static void run_main __P((struct ncr_softc *));
|
||||
static int scsi_dmaok __P((SC_REQ *));
|
||||
static void scsi_main __P((struct ncr_softc *));
|
||||
static void scsi_reset_verbose __P((struct ncr_softc *, const char *));
|
||||
static int scsi_select __P((SC_REQ *, int));
|
||||
static void show_data_sense __P((struct scsi_xfer *));
|
||||
/* static void show_phase __P((struct req_q *, int)); */
|
||||
static void show_request __P((SC_REQ *, char *));
|
||||
static void show_signals __P((u_char, u_char));
|
||||
static void transfer_dma __P((SC_REQ *, u_int, int));
|
||||
static int transfer_pio __P((u_char *, u_char *, u_long *, int));
|
||||
static int wait_req_false __P((void));
|
||||
static int wait_req_true __P((void));
|
||||
|
||||
/*
|
||||
* You might want to call these from the debugger...
|
||||
*/
|
||||
void scsi_show __P((void));
|
||||
void scsi_reset __P((void));
|
||||
/* static void show_phase __P((SC_REQ *, int)); */
|
||||
|
||||
#endif /* _NCR5380REG_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ncr5380var.h,v 1.1 1996/02/22 21:07:12 leo Exp $ */
|
||||
/* $NetBSD: ncr5380var.h,v 1.2 1996/05/15 09:21:54 leo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Leo Weppelman.
|
||||
|
@ -33,75 +33,6 @@
|
|||
#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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue