Add Perforce RCSIDs for easy revision correlation to my local tree.

ahc_pci.c:
	Bring back the AHC_ALLOW_MEMIO option at least until the
	memory mapped I/O problem on the SuperMicro 370DR3 is
	better understood.

aic7xxx.c:
	If we see a spurious SCSI interrupt, attempt to clear it and
	continue by unpausing the sequencer.

	Change the interface to ahc_send_async().  Some async messages
	need to be broadcast to all the luns of a target or all the
	targets of a bus.  This is easier to achieve by passing explicit
	channel, target, and lun parameters instead of attempting to
	construct a device info struct to match.

	Filter the sync parameters for the PPR message in exactly the
	same way we do for an old fashioned SDTR message.

	Correct some typos and correct a panic message.

	Handle rejected PPR messages.

	In ahc_handle_msg_reject(), let ahc_build_transfer_msg() build
	any additional transfer messages instead of doing this inline.

aic7xxx.h:
	Increase the size of both msgout_buf and msgin_buf to
	better accomodate PPR messages.

aic7xxx_freebsd.c:
	Update for change in ahc_send_async() parameters.

aic7xxx_freebsd.h
	Update for change in ahc_send_async() parameters.

	Honor AHC_ALLOW_MEMIO.

aic7xxx_pci.c:
	Check the error register before going into full blown PCI
	interrupt handling.  This avoids a few costly PCI configuration
	space reads when we run our PCI interrupt handler because another
	device sharing our interrupt line is more active than we are.

	Also unpause the sequencer after processing a PCI interrupt.
This commit is contained in:
Justin T. Gibbs 2000-09-22 22:18:05 +00:00
parent ea6487b395
commit c498406d58
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66269
12 changed files with 110 additions and 75 deletions

View File

@ -137,6 +137,7 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
regs = NULL;
regs_type = 0;
regs_id = 0;
#ifdef AHC_ALLOW_MEMIO
if ((command & PCIM_CMD_MEMEN) != 0) {
regs_type = SYS_RES_MEMORY;
regs_id = AHC_PCI_MEMADDR;
@ -163,6 +164,7 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
}
}
}
#endif
if (regs == NULL && (command & PCIM_CMD_PORTEN) != 0) {
regs_type = SYS_RES_IOPORT;
regs_id = AHC_PCI_IOADDR;

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx.c#4 $
*
* $FreeBSD$
*/
@ -798,6 +798,8 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
}
if (status == 0) {
printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
ahc_outb(ahc, CLRINT, CLRSCSIINT);
unpause_sequencer(ahc);
return;
}
}
@ -1487,7 +1489,8 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
/* Update the syncrates in any pending scbs */
ahc_update_pending_syncrates(ahc);
ahc_send_async(ahc, devinfo, AC_TRANSFER_NEG);
ahc_send_async(ahc, devinfo->channel, devinfo->target,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
if (offset != 0) {
printf("%s: target %d synchronous at %sMHz%s, "
@ -1556,7 +1559,8 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
tinfo->current.width = width;
ahc_send_async(ahc, devinfo, AC_TRANSFER_NEG);
ahc_send_async(ahc, devinfo->channel, devinfo->target,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
printf("%s: target %d using %dbit transfers\n",
ahc_name(ahc), devinfo->target,
@ -1593,7 +1597,8 @@ ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, int enable)
if (orig_tagenable != tstate->tagenable) {
ahc_platform_set_tags(ahc, devinfo, enable);
ahc_send_async(ahc, devinfo, AC_TRANSFER_NEG);
ahc_send_async(ahc, devinfo->channel, devinfo->target,
devinfo->lun, AC_TRANSFER_NEG);
}
}
@ -1850,25 +1855,36 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
}
use_ppr = (tinfo->current.transport_version >= 3) || doppr;
if (use_ppr) {
ahc_construct_ppr(ahc, tinfo->goal.period, tinfo->goal.offset,
tinfo->goal.width, tinfo->goal.ppr_options);
} else if (dowide) {
ahc_construct_wdtr(ahc, tinfo->goal.width);
} else if (dosync) {
/*
* Both the PPR message and SDTR message require the
* goal syncrate to be limited to what the target device
* is capable of handling (based on whether an LVD->SE
* expander is on the bus), so combine these two cases.
* Regardless, guarantee that if we are using WDTR and SDTR
* messages that WDTR comes first.
*/
if (use_ppr || (dosync && !dowide)) {
period = tinfo->goal.period;
ppr_options = tinfo->goal.ppr_options;
if (dosync)
ppr_options = 0;
rate = ahc_devlimited_syncrate(ahc, &period, &ppr_options);
offset = tinfo->goal.offset;
ahc_validate_offset(ahc, rate, &offset,
tinfo->current.width);
if (use_ppr)
ahc_construct_ppr(ahc, period, offset,
tinfo->goal.width, ppr_options);
else
ahc_construct_sdtr(ahc, period, offset);
} else {
ahc_construct_wdtr(ahc, tinfo->goal.width);
}
}
/*
* Build an synchronous negotiateion message in our message
* Build a synchronous negotiation message in our message
* buffer based on the input parameters.
*/
static void
@ -1950,7 +1966,7 @@ ahc_handle_message_phase(struct ahc_softc *ahc)
int msgdone;
if (ahc->msgout_len == 0)
panic("REQINIT interrupt with no active message");
panic("HOST_MSG_LOOP interrupt with no active message");
phasemis = bus_phase != P_MESGOUT;
if (phasemis) {
@ -2596,7 +2612,20 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
/* Might be necessary */
last_msg = ahc_inb(ahc, LAST_MSG);
if (ahc_sent_msg(ahc, MSG_EXT_WDTR, /*full*/FALSE)) {
if (ahc_sent_msg(ahc, MSG_EXT_PPR, /*full*/FALSE)) {
/*
* Target does not support the PPR message.
* Attempt to negotiate SPI-2 style.
*/
tinfo->goal.ppr_options = 0;
tinfo->current.transport_version = 2;
tinfo->goal.transport_version = 2;
ahc->msgout_index = 0;
ahc->msgout_len = 0;
ahc_build_transfer_msg(ahc, devinfo);
ahc->msgout_index = 0;
response = 1;
} else if (ahc_sent_msg(ahc, MSG_EXT_WDTR, /*full*/FALSE)) {
/* note 8bit xfers */
printf("%s:%c:%d: refuses WIDE negotiation. Using "
@ -2613,16 +2642,11 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
* sync rate before sending our WDTR.
*/
if (tinfo->goal.period) {
u_int period;
u_int ppr_options;
/* Start the sync negotiation */
period = tinfo->goal.period;
ppr_options = 0;
ahc_devlimited_syncrate(ahc, &period, &ppr_options);
ahc->msgout_index = 0;
ahc->msgout_len = 0;
ahc_construct_sdtr(ahc, period, tinfo->goal.offset);
ahc_build_transfer_msg(ahc, devinfo);
ahc->msgout_index = 0;
response = 1;
}
@ -2852,7 +2876,8 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
/*period*/0, /*offset*/0, /*ppr_options*/0,
AHC_TRANS_CUR, /*paused*/TRUE);
ahc_send_async(ahc, devinfo, AC_SENT_BDR);
ahc_send_async(ahc, devinfo->channel, devinfo->target,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (message != NULL
&& (verbose_level <= bootverbose))
@ -3502,11 +3527,10 @@ ahc_controller_info(struct ahc_softc *ahc, char *buf)
buf += len;
if (ahc->flags & AHC_PAGESCBS)
len = sprintf(buf, "%d/%d SCBs",
sprintf(buf, "%d/%d SCBs",
ahc->scb_data->maxhscbs, AHC_SCB_MAX);
else
len = sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
buf += len;
sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
}
/*
@ -4714,7 +4738,8 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
}
#endif
/* Notify the XPT that a bus reset occurred */
ahc_send_async(ahc, &devinfo, AC_BUS_RESET);
ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
/*
* Revert to async/narrow transfers until we renegotiate.

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx.h#4 $
*
* $FreeBSD$
*/
@ -897,8 +897,8 @@ struct ahc_softc {
*/
uint8_t send_msg_perror;
ahc_msg_type msg_type;
uint8_t msgout_buf[8];/* Message we are sending */
uint8_t msgin_buf[8]; /* Message we are receiving */
uint8_t msgout_buf[12];/* Message we are sending */
uint8_t msgin_buf[12];/* Message we are receiving */
u_int msgout_len; /* Length of message to send */
u_int msgout_index; /* Current index in msgout */
u_int msgin_index; /* Current index in msgin */

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx.reg#3 $
*
* $FreeBSD$
*/

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx_93cx6.c#3 $
*
* $FreeBSD$
*/

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx_93cx6.h#3 $
*
* $FreeBSD$
*/

View File

@ -68,25 +68,24 @@ static void ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
static void ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim,
union ccb *ccb);
static int ahc_create_path(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo,
char channel, u_int target, u_int lun,
struct cam_path **path);
static void ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb);
static int
ahc_create_path(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
struct cam_path **path)
ahc_create_path(struct ahc_softc *ahc, char channel, u_int target,
u_int lun, struct cam_path **path)
{
path_id_t path_id;
if (devinfo->channel == 'B')
if (channel == 'B')
path_id = cam_sim_path(ahc->platform_data->sim_b);
else
path_id = cam_sim_path(ahc->platform_data->sim);
return (xpt_create_path(path, /*periph*/NULL,
path_id, devinfo->target,
devinfo->lun));
path_id, target, lun));
}
/*
@ -1713,18 +1712,16 @@ ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
}
void
ahc_send_async(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ac_code code)
ahc_send_async(struct ahc_softc *ahc, char channel, u_int target,
u_int lun, ac_code code)
{
struct ahc_devinfo mod_devinfo;
struct ccb_trans_settings cts;
struct cam_path *path;
void *arg;
int error;
mod_devinfo = *devinfo;
mod_devinfo.lun = CAM_LUN_WILDCARD;
arg = NULL;
error = ahc_create_path(ahc, &mod_devinfo, &path);
error = ahc_create_path(ahc, channel, target, lun, &path);
if (error != CAM_REQ_CMP)
return;
@ -1737,10 +1734,11 @@ ahc_send_async(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ac_code code)
cts.flags = CCB_TRANS_CURRENT_SETTINGS;
#endif
cts.ccb_h.path = path;
cts.ccb_h.target_id = devinfo->target;
cts.ccb_h.target_lun = devinfo->lun;
ahc_get_tran_settings(ahc, devinfo->our_scsiid,
devinfo->channel, &cts);
cts.ccb_h.target_id = target;
cts.ccb_h.target_lun = lun;
ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id
: ahc->our_id_b,
channel, &cts);
arg = &cts;
break;
case AC_SENT_BDR:

View File

@ -51,8 +51,10 @@
#if NPCI > 0
#define AHC_SUPPORT_PCI 1
#ifdef AHC_ALLOW_MEMIO
#include <machine/bus_memio.h>
#endif
#endif
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/clock.h>
@ -447,5 +449,6 @@ int ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc);
/************************ Misc Function Declarations **************************/
timeout_t ahc_timeout;
void ahc_done(struct ahc_softc *ahc, struct scb *scb);
void ahc_send_async(struct ahc_softc *, struct ahc_devinfo *, ac_code);
void ahc_send_async(struct ahc_softc *, char /*channel*/,
u_int /*target*/, u_int /*lun*/, ac_code);
#endif /* _AIC7XXX_FREEBSD_H_ */

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx_inline.h#3 $
*
* $FreeBSD$
*/

View File

@ -68,25 +68,24 @@ static void ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
static void ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim,
union ccb *ccb);
static int ahc_create_path(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo,
char channel, u_int target, u_int lun,
struct cam_path **path);
static void ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb);
static int
ahc_create_path(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
struct cam_path **path)
ahc_create_path(struct ahc_softc *ahc, char channel, u_int target,
u_int lun, struct cam_path **path)
{
path_id_t path_id;
if (devinfo->channel == 'B')
if (channel == 'B')
path_id = cam_sim_path(ahc->platform_data->sim_b);
else
path_id = cam_sim_path(ahc->platform_data->sim);
return (xpt_create_path(path, /*periph*/NULL,
path_id, devinfo->target,
devinfo->lun));
path_id, target, lun));
}
/*
@ -1713,18 +1712,16 @@ ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
}
void
ahc_send_async(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ac_code code)
ahc_send_async(struct ahc_softc *ahc, char channel, u_int target,
u_int lun, ac_code code)
{
struct ahc_devinfo mod_devinfo;
struct ccb_trans_settings cts;
struct cam_path *path;
void *arg;
int error;
mod_devinfo = *devinfo;
mod_devinfo.lun = CAM_LUN_WILDCARD;
arg = NULL;
error = ahc_create_path(ahc, &mod_devinfo, &path);
error = ahc_create_path(ahc, channel, target, lun, &path);
if (error != CAM_REQ_CMP)
return;
@ -1737,10 +1734,11 @@ ahc_send_async(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ac_code code)
cts.flags = CCB_TRANS_CURRENT_SETTINGS;
#endif
cts.ccb_h.path = path;
cts.ccb_h.target_id = devinfo->target;
cts.ccb_h.target_lun = devinfo->lun;
ahc_get_tran_settings(ahc, devinfo->our_scsiid,
devinfo->channel, &cts);
cts.ccb_h.target_id = target;
cts.ccb_h.target_lun = lun;
ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id
: ahc->our_id_b,
channel, &cts);
arg = &cts;
break;
case AC_SENT_BDR:

View File

@ -51,8 +51,10 @@
#if NPCI > 0
#define AHC_SUPPORT_PCI 1
#ifdef AHC_ALLOW_MEMIO
#include <machine/bus_memio.h>
#endif
#endif
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <machine/clock.h>
@ -447,5 +449,6 @@ int ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc);
/************************ Misc Function Declarations **************************/
timeout_t ahc_timeout;
void ahc_done(struct ahc_softc *ahc, struct scb *scb);
void ahc_send_async(struct ahc_softc *, struct ahc_devinfo *, ac_code);
void ahc_send_async(struct ahc_softc *, char /*channel*/,
u_int /*target*/, u_int /*lun*/, ac_code);
#endif /* _AIC7XXX_FREEBSD_H_ */

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: //depot/src/aic7xxx/aic7xxx_pci.c#4 $
*
* $FreeBSD$
*/
@ -1569,25 +1569,29 @@ read_brdctl(ahc)
void
ahc_pci_intr(struct ahc_softc *ahc)
{
uint8_t status1;
u_int error;
u_int status1;
error = ahc_inb(ahc, ERROR);
if ((error & PCIERRSTAT) == 0)
return;
status1 = ahc_pci_read_config(ahc->dev_softc,
PCIR_STATUS + 1, /*bytes*/1);
if (status1 & (DPE|SSE|RMA|RTA|STA|DPR)) {
printf("%s: PCI Interrupt at seqaddr = 0x%x\n",
printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
ahc_name(ahc),
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
}
if (status1 & DPE) {
printf("%s: Data Parity Error Detected during address "
"or write data phase\n", ahc_name(ahc));
}
if (status1 & SSE) {
printf("%s: Signal System Error Detected\n", ahc_name(ahc));
printf("%s: Signaled System Error Detected\n", ahc_name(ahc));
}
if (status1 & RMA) {
printf("%s: Received a Master Abort\n", ahc_name(ahc));
printf("%s: Signaled a Master Abort\n", ahc_name(ahc));
}
if (status1 & RTA) {
printf("%s: Received a Target Abort\n", ahc_name(ahc));
@ -1609,6 +1613,8 @@ ahc_pci_intr(struct ahc_softc *ahc)
if (status1 & (DPR|RMA|RTA)) {
ahc_outb(ahc, CLRINT, CLRPARERR);
}
unpause_sequencer(ahc);
}
static int