Commit a649f9b4 authored by Justin T. Gibbs's avatar Justin T. Gibbs

Merge http://linux.bkbits.net/linux-2.5

into overdrive.btc.adaptec.com:/usr/home/gibbs/bk/linux-2.5
parents eb0a5728 a4731d08
...@@ -371,9 +371,33 @@ The following information is available in this file: ...@@ -371,9 +371,33 @@ The following information is available in this file:
- Fax Technical Support at +852-2869-7100 - Fax Technical Support at +852-2869-7100
------------------------------------------------------------------- -------------------------------------------------------------------
/*
(c) 2003 Adaptec, Inc. All Rights Reserved. No part of this * Copyright (c) 2003 Adaptec Inc. 691 S. Milpitas Blvd., Milpitas CA 95035 USA.
publication may be reproduced, stored in a retrieval system, or * All rights reserved.
transmitted in any form or by any means, electronic, mechanical, *
photocopying, recording or otherwise, without prior written consent * You are permitted to redistribute, use and modify this README file in whole
of Adaptec, Inc., 691 South Milpitas Blvd., Milpitas, CA 95035. * or in part in conjunction with redistribution of software governed by the
* General Public License, provided that the following conditions are met:
* 1. Redistributions of README file must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 3. Modifications or new contributions must be attributed in a copyright
* notice identifying the author ("Contributor") and added below the
* original copyright notice. The copyright notice is for purposes of
* identifying contributors and should not be deemed as permission to alter
* the permissions given by Adaptec.
*
* THIS README FILE IS PROVIDED BY ADAPTEC AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ANY
* WARRANTIES OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* ADAPTEC OR CONTRIBUTORS 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 README
* FILE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
...@@ -132,6 +132,16 @@ The following information is available in this file: ...@@ -132,6 +132,16 @@ The following information is available in this file:
2. Version History 2. Version History
6.2.33 - Dynamically disable PCI parity error reporting after
10 errors are reported to the user. These errors are
the result of some other device issuing PCI transactions
with bad parity. Once the user has been informed of the
problem, continuing to report the errors just degrades
our performance.
6.2.32 - Dynamically sized S/G lists to avoid SCSI malloc
pool fragmentation and SCSI mid-layer deadlock.
6.2.28 - Domain Validation Fixes 6.2.28 - Domain Validation Fixes
PCI parity error disable PCI parity error disable
Enhanced Memory Mapped I/O probe Enhanced Memory Mapped I/O probe
...@@ -160,6 +170,7 @@ The following information is available in this file: ...@@ -160,6 +170,7 @@ The following information is available in this file:
Default Value: 0x0000 Default Value: 0x0000
----------------------------------------------------------------- -----------------------------------------------------------------
Option: no_probe Option: no_probe
Option: probe_eisa_vl
Definition: Do not probe for EISA/VLB controllers. Definition: Do not probe for EISA/VLB controllers.
This is a toggle. If the driver is compiled This is a toggle. If the driver is compiled
to not probe EISA/VLB controllers by default, to not probe EISA/VLB controllers by default,
...@@ -339,9 +350,33 @@ The following information is available in this file: ...@@ -339,9 +350,33 @@ The following information is available in this file:
- Fax Technical Support at +852-2869-7100 - Fax Technical Support at +852-2869-7100
------------------------------------------------------------------- -------------------------------------------------------------------
/*
(c) 2002 Adaptec, Inc. All Rights Reserved. No part of this * Copyright (c) 2003 Adaptec Inc. 691 S. Milpitas Blvd., Milpitas CA 95035 USA.
publication may be reproduced, stored in a retrieval system, or * All rights reserved.
transmitted in any form or by any means, electronic, mechanical, *
photocopying, recording or otherwise, without prior written consent * You are permitted to redistribute, use and modify this README file in whole
of Adaptec, Inc., 691 South Milpitas Blvd., Milpitas, CA 95035. * or in part in conjunction with redistribution of software governed by the
* General Public License, provided that the following conditions are met:
* 1. Redistributions of README file must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 3. Modifications or new contributions must be attributed in a copyright
* notice identifying the author ("Contributor") and added below the
* original copyright notice. The copyright notice is for purposes of
* identifying contributors and should not be deemed as permission to alter
* the permissions given by Adaptec.
*
* THIS README FILE IS PROVIDED BY ADAPTEC AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ANY
* WARRANTIES OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* ADAPTEC OR CONTRIBUTORS 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 README
* FILE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7770.c#29 $ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#30 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -314,7 +314,7 @@ aha2840_load_seeprom(struct ahc_softc *ahc) ...@@ -314,7 +314,7 @@ aha2840_load_seeprom(struct ahc_softc *ahc)
if (bootverbose) if (bootverbose)
printf("%s: Reading SEEPROM...", ahc_name(ahc)); printf("%s: Reading SEEPROM...", ahc_name(ahc));
have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
/*start_addr*/0, sizeof(sc)/2); /*start_addr*/0, sizeof(*sc)/2);
if (have_seeprom) { if (have_seeprom) {
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#88 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#89 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -494,13 +494,11 @@ struct hardware_scb { ...@@ -494,13 +494,11 @@ struct hardware_scb {
* transfer. * transfer.
*/ */
#define SG_PTR_MASK 0xFFFFFFF8 #define SG_PTR_MASK 0xFFFFFFF8
/*16*/ uint16_t tag; /*16*/ uint64_t dataptr;
/*18*/ uint8_t cdb_len; /*24*/ uint32_t datacnt; /* Byte 3 is spare. */
/*19*/ uint8_t task_management; /*28*/ uint32_t sgptr;
/*20*/ uint32_t next_hscb_busaddr; /*32*/ uint32_t hscb_busaddr;
/*24*/ uint64_t dataptr; /*36*/ uint32_t next_hscb_busaddr;
/*32*/ uint32_t datacnt; /* Byte 3 is spare. */
/*36*/ uint32_t sgptr;
/*40*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */ /*40*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */
/*41*/ uint8_t scsiid; /* /*41*/ uint8_t scsiid; /*
* Selection out Id * Selection out Id
...@@ -508,8 +506,10 @@ struct hardware_scb { ...@@ -508,8 +506,10 @@ struct hardware_scb {
*/ */
/*42*/ uint8_t lun; /*42*/ uint8_t lun;
/*43*/ uint8_t task_attribute; /*43*/ uint8_t task_attribute;
/*44*/ uint32_t hscb_busaddr; /*44*/ uint8_t cdb_len;
/******* Long lun field only downloaded for full 8 byte lun support *******/ /*45*/ uint8_t task_management;
/*46*/ uint16_t tag; /* Reused by Sequencer. */
/********** Long lun field only downloaded for full 8 byte lun support ********/
/*48*/ uint8_t pkt_long_lun[8]; /*48*/ uint8_t pkt_long_lun[8];
/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/ /******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
/*56*/ uint8_t spare[8]; /*56*/ uint8_t spare[8];
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $"
/* /*
* This file is processed by the aic7xxx_asm utility for use in assembling * This file is processed by the aic7xxx_asm utility for use in assembling
...@@ -194,7 +194,8 @@ register SEQINTCODE { ...@@ -194,7 +194,8 @@ register SEQINTCODE {
TRACEPOINT1, TRACEPOINT1,
TRACEPOINT2, TRACEPOINT2,
TRACEPOINT3, TRACEPOINT3,
SAW_HWERR SAW_HWERR,
BAD_SCB_STATUS
} }
} }
...@@ -3484,9 +3485,6 @@ scratch_ram { ...@@ -3484,9 +3485,6 @@ scratch_ram {
LONGJMP_ADDR { LONGJMP_ADDR {
size 2 size 2
} }
LONGJMP_SCB {
size 2
}
ACCUM_SAVE { ACCUM_SAVE {
size 1 size 1
} }
...@@ -3799,23 +3797,6 @@ scb { ...@@ -3799,23 +3797,6 @@ scb {
size 4 size 4
alias SCB_NEXT_COMPLETE alias SCB_NEXT_COMPLETE
} }
SCB_TAG {
size 2
}
SCB_CDB_LEN {
size 1
field SCB_CDB_LEN_PTR 0x80 /* CDB in host memory */
}
SCB_TASK_MANAGEMENT {
size 1
}
SCB_NEXT {
alias SCB_NEXT_SCB_BUSADDR
size 2
}
SCB_NEXT2 {
size 2
}
SCB_DATAPTR { SCB_DATAPTR {
size 8 size 8
} }
...@@ -3834,6 +3815,16 @@ scb { ...@@ -3834,6 +3815,16 @@ scb {
field SG_FULL_RESID 0x02 /* In the first byte */ field SG_FULL_RESID 0x02 /* In the first byte */
field SG_LIST_NULL 0x01 /* In the first byte */ field SG_LIST_NULL 0x01 /* In the first byte */
} }
SCB_BUSADDR {
size 4
}
SCB_NEXT {
alias SCB_NEXT_SCB_BUSADDR
size 2
}
SCB_NEXT2 {
size 2
}
SCB_CONTROL { SCB_CONTROL {
size 1 size 1
field TARGET_SCB 0x80 field TARGET_SCB 0x80
...@@ -3856,8 +3847,16 @@ scb { ...@@ -3856,8 +3847,16 @@ scb {
SCB_TASK_ATTRIBUTE { SCB_TASK_ATTRIBUTE {
size 1 size 1
} }
SCB_BUSADDR { SCB_CDB_LEN {
size 4 size 1
field SCB_CDB_LEN_PTR 0x80 /* CDB in host memory */
}
SCB_TASK_MANAGEMENT {
size 1
}
SCB_TAG {
alias SCB_FIFO_USE_COUNT
size 2
} }
SCB_SPARE { SCB_SPARE {
size 8 size 8
......
This diff is collapsed.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#178 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#190 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -556,6 +556,26 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -556,6 +556,26 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
ahd_name(ahd), seqintcode); ahd_name(ahd), seqintcode);
#endif #endif
switch (seqintcode) { switch (seqintcode) {
case BAD_SCB_STATUS:
{
struct scb *scb;
u_int scbid;
int cmds_pending;
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
if (scb != NULL) {
ahd_complete_scb(ahd, scb);
} else {
printf("%s: WARNING no command for scb %d "
"(bad status)\n", ahd_name(ahd), scbid);
ahd_dump_card_state(ahd);
}
cmds_pending = ahd_inw(ahd, CMDS_PENDING);
if (cmds_pending > 0)
ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1);
break;
}
case ENTERING_NONPACK: case ENTERING_NONPACK:
{ {
struct scb *scb; struct scb *scb;
...@@ -604,7 +624,16 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -604,7 +624,16 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
break; break;
case STATUS_OVERRUN: case STATUS_OVERRUN:
{ {
printf("%s: Status Overrun", ahd_name(ahd)); struct scb *scb;
u_int scbid;
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
if (scb != NULL)
ahd_print_path(ahd, scb);
else
printf("%s: ", ahd_name(ahd));
printf("SCB %d Packetized Status Overrun", scbid);
ahd_dump_card_state(ahd); ahd_dump_card_state(ahd);
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
break; break;
...@@ -1023,7 +1052,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -1023,7 +1052,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
switch (scb->hscb->task_management) { switch (scb->hscb->task_management) {
case SIU_TASKMGMT_ABORT_TASK: case SIU_TASKMGMT_ABORT_TASK:
tag = scb->hscb->tag; tag = SCB_GET_TAG(scb);
case SIU_TASKMGMT_ABORT_TASK_SET: case SIU_TASKMGMT_ABORT_TASK_SET:
case SIU_TASKMGMT_CLEAR_TASK_SET: case SIU_TASKMGMT_CLEAR_TASK_SET:
lun = scb->hscb->lun; lun = scb->hscb->lun;
...@@ -1087,7 +1116,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ...@@ -1087,7 +1116,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0); ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
SCB_GET_CHANNEL(ahd, scb), SCB_GET_CHANNEL(ahd, scb),
SCB_GET_LUN(scb), scb->hscb->tag, SCB_GET_LUN(scb), SCB_GET_TAG(scb),
ROLE_INITIATOR, /*status*/0, ROLE_INITIATOR, /*status*/0,
SEARCH_REMOVE); SEARCH_REMOVE);
} }
...@@ -1166,7 +1195,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) ...@@ -1166,7 +1195,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
/* /*
* A change in I/O mode is equivalent to a bus reset. * A change in I/O mode is equivalent to a bus reset.
*/ */
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
ahd_pause(ahd); ahd_pause(ahd);
ahd_setup_iocell_workaround(ahd); ahd_setup_iocell_workaround(ahd);
ahd_unpause(ahd); ahd_unpause(ahd);
...@@ -2183,6 +2212,13 @@ ahd_clear_critical_section(struct ahd_softc *ahd) ...@@ -2183,6 +2212,13 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP); ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
ahd_outb(ahd, SIMODE1, simode1); ahd_outb(ahd, SIMODE1, simode1);
/*
* SCSIINT seems to glitch occassionally when
* the interrupt masks are restored. Clear SCSIINT
* one more time so that only persistent errors
* are seen as a real interrupt.
*/
ahd_outb(ahd, CLRINT, CLRSCSIINT);
} }
ahd_restore_modes(ahd, saved_modes); ahd_restore_modes(ahd, saved_modes);
} }
...@@ -4887,7 +4923,6 @@ ahd_free(struct ahd_softc *ahd) ...@@ -4887,7 +4923,6 @@ ahd_free(struct ahd_softc *ahd)
{ {
int i; int i;
ahd_fini_scbdata(ahd);
switch (ahd->init_level) { switch (ahd->init_level) {
default: default:
case 5: case 5:
...@@ -4919,6 +4954,7 @@ ahd_free(struct ahd_softc *ahd) ...@@ -4919,6 +4954,7 @@ ahd_free(struct ahd_softc *ahd)
ahd_dma_tag_destroy(ahd, ahd->parent_dmat); ahd_dma_tag_destroy(ahd, ahd->parent_dmat);
#endif #endif
ahd_platform_free(ahd); ahd_platform_free(ahd);
ahd_fini_scbdata(ahd);
for (i = 0; i < AHD_NUM_TARGETS; i++) { for (i = 0; i < AHD_NUM_TARGETS; i++) {
struct ahd_tmode_tstate *tstate; struct ahd_tmode_tstate *tstate;
...@@ -5481,7 +5517,7 @@ ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) ...@@ -5481,7 +5517,7 @@ ahd_free_scb(struct ahd_softc *ahd, struct scb *scb)
/* Clean up for the next user */ /* Clean up for the next user */
scb->flags = SCB_FLAG_NONE; scb->flags = SCB_FLAG_NONE;
scb->hscb->control = 0; scb->hscb->control = 0;
ahd->scb_data.scbindex[scb->hscb->tag] = NULL; ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL;
if (scb->col_scb == NULL) { if (scb->col_scb == NULL) {
...@@ -5584,8 +5620,8 @@ ahd_alloc_scbs(struct ahd_softc *ahd) ...@@ -5584,8 +5620,8 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
if (scb_data->sgs_left != 0) { if (scb_data->sgs_left != 0) {
int offset; int offset;
offset = ahd_sglist_allocsize(ahd) offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd))
- (scb_data->sgs_left * ahd_sglist_size(ahd)); - scb_data->sgs_left) * ahd_sglist_size(ahd);
sg_map = SLIST_FIRST(&scb_data->sg_maps); sg_map = SLIST_FIRST(&scb_data->sg_maps);
segs = sg_map->vaddr + offset; segs = sg_map->vaddr + offset;
sg_busaddr = sg_map->physaddr + offset; sg_busaddr = sg_map->physaddr + offset;
...@@ -5894,7 +5930,7 @@ ahd_init(struct ahd_softc *ahd) ...@@ -5894,7 +5930,7 @@ ahd_init(struct ahd_softc *ahd)
* specially from the DMA safe memory chunk used for the QOUTFIFO. * specially from the DMA safe memory chunk used for the QOUTFIFO.
*/ */
ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
ahd->next_queued_hscb->hscb_busaddr = next_baddr; ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
ahd->init_level++; ahd->init_level++;
...@@ -6056,7 +6092,6 @@ ahd_chip_init(struct ahd_softc *ahd) ...@@ -6056,7 +6092,6 @@ ahd_chip_init(struct ahd_softc *ahd)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
ahd_outw(ahd, LONGJMP_SCB, SCB_LIST_NULL);
ahd_outb(ahd, SG_STATE, 0); ahd_outb(ahd, SG_STATE, 0);
ahd_outb(ahd, CLRSEQINTSRC, 0xFF); ahd_outb(ahd, CLRSEQINTSRC, 0xFF);
ahd_outb(ahd, SEQIMODE, ahd_outb(ahd, SEQIMODE,
...@@ -6605,24 +6640,29 @@ ahd_enable_coalessing(struct ahd_softc *ahd, int enable) ...@@ -6605,24 +6640,29 @@ ahd_enable_coalessing(struct ahd_softc *ahd, int enable)
void void
ahd_pause_and_flushwork(struct ahd_softc *ahd) ahd_pause_and_flushwork(struct ahd_softc *ahd)
{ {
ahd_mode_state saved_modes; u_int intstat;
u_int intstat; u_int maxloops;
u_int maxloops; u_int qfreeze_cnt;
int paused;
maxloops = 1000; maxloops = 1000;
ahd->flags |= AHD_ALL_INTERRUPTS; ahd->flags |= AHD_ALL_INTERRUPTS;
paused = FALSE; ahd_pause(ahd);
/*
* Increment the QFreeze Count so that the sequencer
* will not start new selections. We do this only
* until we are safely paused without further selections
* pending.
*/
ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1);
ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);
do { do {
struct scb *waiting_scb; struct scb *waiting_scb;
if (paused) ahd_unpause(ahd);
ahd_unpause(ahd);
ahd_intr(ahd); ahd_intr(ahd);
ahd_pause(ahd); ahd_pause(ahd);
paused = TRUE;
ahd_clear_critical_section(ahd); ahd_clear_critical_section(ahd);
saved_modes = ahd_save_modes(ahd); intstat = ahd_inb(ahd, INTSTAT);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0) if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)
ahd_outb(ahd, SCSISEQ0, ahd_outb(ahd, SCSISEQ0,
...@@ -6639,22 +6679,32 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) ...@@ -6639,22 +6679,32 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
&& (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0) && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0)
ahd_outb(ahd, SCSISEQ0, ahd_outb(ahd, SCSISEQ0,
ahd_inb(ahd, SCSISEQ0) | ENSELO); ahd_inb(ahd, SCSISEQ0) | ENSELO);
intstat = ahd_inb(ahd, INTSTAT);
} while (--maxloops } while (--maxloops
&& (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0) && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)
&& ((intstat & INT_PEND) != 0 && ((intstat & INT_PEND) != 0
|| (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)))); || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
|| (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
if (maxloops == 0) { if (maxloops == 0) {
printf("Infinite interrupt loop, INTSTAT = %x", printf("Infinite interrupt loop, INTSTAT = %x",
ahd_inb(ahd, INTSTAT)); ahd_inb(ahd, INTSTAT));
} }
qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
if (qfreeze_cnt == 0) {
printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n",
ahd_name(ahd));
} else {
qfreeze_cnt--;
}
ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
if (qfreeze_cnt == 0)
ahd_outb(ahd, SEQ_FLAGS2,
ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
ahd_flush_qoutfifo(ahd); ahd_flush_qoutfifo(ahd);
ahd_platform_flushwork(ahd); ahd_platform_flushwork(ahd);
ahd->flags &= ~AHD_ALL_INTERRUPTS; ahd->flags &= ~AHD_ALL_INTERRUPTS;
ahd_restore_modes(ahd, saved_modes);
} }
int int
...@@ -7514,14 +7564,17 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) ...@@ -7514,14 +7564,17 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_outb(ahd, DFFSTAT, next_fifo); ahd_outb(ahd, DFFSTAT, next_fifo);
} while (next_fifo != fifo); } while (next_fifo != fifo);
/* /*
* Reset the bus if we are initiating this reset * Reset the bus if we are initiating this reset
*/ */
ahd_clear_msg_state(ahd); ahd_clear_msg_state(ahd);
ahd_outb(ahd, SIMODE1, ahd_outb(ahd, SIMODE1,
ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE)); ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE));
if (initiate_reset) if (initiate_reset)
ahd_reset_current_bus(ahd); ahd_reset_current_bus(ahd);
ahd_clear_intstat(ahd); ahd_clear_intstat(ahd);
/* /*
...@@ -7719,9 +7772,6 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) ...@@ -7719,9 +7772,6 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
hscb = scb->hscb; hscb = scb->hscb;
/* Freeze the queue until the client sees the error. */ /* Freeze the queue until the client sees the error. */
ahd_pause(ahd);
ahd_clear_critical_section(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
ahd_freeze_devq(ahd, scb); ahd_freeze_devq(ahd, scb);
ahd_freeze_scb(scb); ahd_freeze_scb(scb);
qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
...@@ -7734,7 +7784,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) ...@@ -7734,7 +7784,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
if (qfreeze_cnt == 0) if (qfreeze_cnt == 0)
ahd_outb(ahd, SEQ_FLAGS2, ahd_outb(ahd, SEQ_FLAGS2,
ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
ahd_unpause(ahd);
/* Don't want to clobber the original sense code */ /* Don't want to clobber the original sense code */
if ((scb->flags & SCB_SENSE) != 0) { if ((scb->flags & SCB_SENSE) != 0) {
/* /*
...@@ -8592,11 +8642,11 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8592,11 +8642,11 @@ ahd_dump_card_state(struct ahd_softc *ahd)
LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) { LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
if (i++ > AHD_SCB_MAX) if (i++ > AHD_SCB_MAX)
break; break;
cur_col = printf("\n%3d ", SCB_GET_TAG(scb)); cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
ahd_inb(ahd, SCB_FIFO_USE_COUNT));
ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60); ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60);
ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60); ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60);
ahd_scb_tag_print(ahd_inb(ahd, SCB_TAG), &cur_col, 60);
} }
printf("\nTotal %d\n", i); printf("\nTotal %d\n", i);
...@@ -8659,12 +8709,10 @@ ahd_dump_card_state(struct ahd_softc *ahd) ...@@ -8659,12 +8709,10 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i); ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
fifo_scbptr = ahd_get_scbptr(ahd); fifo_scbptr = ahd_get_scbptr(ahd);
printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, " printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
"SCB 0x%x, LJSCB 0x%x\n",
ahd_name(ahd), i, ahd_name(ahd), i,
(dffstat & (FIFO0FREE << i)) ? "Free" : "Active", (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr, ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
ahd_inw(ahd, LONGJMP_SCB));
cur_col = 0; cur_col = 0;
ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50); ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50);
ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50); ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#44 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#48 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -223,7 +223,7 @@ ahd_unpause(struct ahd_softc *ahd) ...@@ -223,7 +223,7 @@ ahd_unpause(struct ahd_softc *ahd)
ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
} }
if ((ahd_inb(ahd, INTSTAT) & ~(SWTMINT | CMDCMPLT)) == 0) if ((ahd_inb(ahd, INTSTAT) & ~CMDCMPLT) == 0)
ahd_outb(ahd, HCNTRL, ahd->unpause); ahd_outb(ahd, HCNTRL, ahd->unpause);
ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN); ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN);
...@@ -298,9 +298,12 @@ ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb) ...@@ -298,9 +298,12 @@ ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb)
scb->hscb->datacnt = sg->len; scb->hscb->datacnt = sg->len;
} else { } else {
struct ahd_dma_seg *sg; struct ahd_dma_seg *sg;
uint32_t *dataptr_words;
sg = (struct ahd_dma_seg *)scb->sg_list; sg = (struct ahd_dma_seg *)scb->sg_list;
scb->hscb->dataptr = sg->addr; dataptr_words = (uint32_t*)&scb->hscb->dataptr;
dataptr_words[0] = sg->addr;
dataptr_words[1] = 0;
if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
uint64_t high_addr; uint64_t high_addr;
...@@ -777,12 +780,15 @@ ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb) ...@@ -777,12 +780,15 @@ ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb)
#ifdef AHD_DEBUG #ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_QUEUE) != 0) { if ((ahd_debug & AHD_SHOW_QUEUE) != 0) {
uint64_t host_dataptr;
host_dataptr = ahd_le64toh(scb->hscb->dataptr);
printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n", printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
ahd_name(ahd), ahd_name(ahd),
SCB_GET_TAG(scb), scb->hscb->hscb_busaddr, SCB_GET_TAG(scb), ahd_le32toh(scb->hscb->hscb_busaddr),
(u_int)((scb->hscb->dataptr >> 32) & 0xFFFFFFFF), (u_int)((host_dataptr >> 32) & 0xFFFFFFFF),
(u_int)(scb->hscb->dataptr & 0xFFFFFFFF), (u_int)(host_dataptr & 0xFFFFFFFF),
scb->hscb->datacnt); ahd_le32toh(scb->hscb->datacnt));
} }
#endif #endif
/* Tell the adapter about the newly queued SCB */ /* Tell the adapter about the newly queued SCB */
...@@ -805,7 +811,7 @@ ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb) ...@@ -805,7 +811,7 @@ ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb)
static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op); static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op);
static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op); static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op);
static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd); static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd);
static __inline void ahd_intr(struct ahd_softc *ahd); static __inline int ahd_intr(struct ahd_softc *ahd);
static __inline void static __inline void
ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) ahd_sync_qoutfifo(struct ahd_softc *ahd, int op)
...@@ -864,7 +870,7 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) ...@@ -864,7 +870,7 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd)
/* /*
* Catch an interrupt from the adapter * Catch an interrupt from the adapter
*/ */
static __inline void static __inline int
ahd_intr(struct ahd_softc *ahd) ahd_intr(struct ahd_softc *ahd)
{ {
u_int intstat; u_int intstat;
...@@ -876,7 +882,7 @@ ahd_intr(struct ahd_softc *ahd) ...@@ -876,7 +882,7 @@ ahd_intr(struct ahd_softc *ahd)
* so just return. This is likely just a shared * so just return. This is likely just a shared
* interrupt. * interrupt.
*/ */
return; return (0);
} }
/* /*
...@@ -891,6 +897,9 @@ ahd_intr(struct ahd_softc *ahd) ...@@ -891,6 +897,9 @@ ahd_intr(struct ahd_softc *ahd)
else else
intstat = ahd_inb(ahd, INTSTAT); intstat = ahd_inb(ahd, INTSTAT);
if ((intstat & INT_PEND) == 0)
return (0);
if (intstat & CMDCMPLT) { if (intstat & CMDCMPLT) {
ahd_outb(ahd, CLRINT, CLRCMDINT); ahd_outb(ahd, CLRINT, CLRCMDINT);
...@@ -924,28 +933,25 @@ ahd_intr(struct ahd_softc *ahd) ...@@ -924,28 +933,25 @@ ahd_intr(struct ahd_softc *ahd)
#endif #endif
} }
if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) /*
/* Hot eject */ * Handle statuses that may invalidate our cached
return; * copy of INTSTAT separately.
*/
if ((intstat & INT_PEND) == 0) if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) {
return; /* Hot eject. Do nothing */
} else if (intstat & HWERRINT) {
if (intstat & HWERRINT) {
ahd_handle_hwerrint(ahd); ahd_handle_hwerrint(ahd);
return; } else if ((intstat & (PCIINT|SPLTINT)) != 0) {
}
if ((intstat & (PCIINT|SPLTINT)) != 0) {
ahd->bus_intr(ahd); ahd->bus_intr(ahd);
return; } else {
}
if ((intstat & SEQINT) != 0) if ((intstat & SEQINT) != 0)
ahd_handle_seqint(ahd, intstat); ahd_handle_seqint(ahd, intstat);
if ((intstat & SCSIINT) != 0) if ((intstat & SCSIINT) != 0)
ahd_handle_scsiint(ahd, intstat); ahd_handle_scsiint(ahd, intstat);
}
return (1);
} }
#endif /* _AIC79XX_INLINE_H_ */ #endif /* _AIC79XX_INLINE_H_ */
This diff is collapsed.
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#121 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#130 $
* *
*/ */
#ifndef _AIC79XX_LINUX_H_ #ifndef _AIC79XX_LINUX_H_
...@@ -139,7 +139,7 @@ typedef Scsi_Cmnd *ahd_io_ctx_t; ...@@ -139,7 +139,7 @@ typedef Scsi_Cmnd *ahd_io_ctx_t;
#endif /* BYTE_ORDER */ #endif /* BYTE_ORDER */
/************************* Configuration Data *********************************/ /************************* Configuration Data *********************************/
extern int aic79xx_allow_memio; extern uint32_t aic79xx_allow_memio;
extern int aic79xx_detect_complete; extern int aic79xx_detect_complete;
extern Scsi_Host_Template aic79xx_driver_template; extern Scsi_Host_Template aic79xx_driver_template;
...@@ -255,7 +255,7 @@ typedef struct timer_list ahd_timer_t; ...@@ -255,7 +255,7 @@ typedef struct timer_list ahd_timer_t;
/***************************** Timer Facilities *******************************/ /***************************** Timer Facilities *******************************/
#define ahd_timer_init init_timer #define ahd_timer_init init_timer
#define ahd_timer_stop del_timer #define ahd_timer_stop del_timer_sync
typedef void ahd_linux_callback_t (u_long); typedef void ahd_linux_callback_t (u_long);
static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec, static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec,
ahd_callback_t *func, void *arg); ahd_callback_t *func, void *arg);
...@@ -293,7 +293,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -293,7 +293,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#define AHD_SCSI_HAS_HOST_LOCK 0 #define AHD_SCSI_HAS_HOST_LOCK 0
#endif #endif
#define AIC79XX_DRIVER_VERSION "1.3.5" #define AIC79XX_DRIVER_VERSION "1.3.8"
/**************************** Front End Queues ********************************/ /**************************** Front End Queues ********************************/
/* /*
...@@ -488,7 +488,18 @@ struct ahd_linux_target { ...@@ -488,7 +488,18 @@ struct ahd_linux_target {
* manner and are allocated below 4GB, the number of S/G segments is * manner and are allocated below 4GB, the number of S/G segments is
* unrestricted. * unrestricted.
*/ */
#define AHD_NSEG 128 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* We dynamically adjust the number of segments in pre-2.5 kernels to
* avoid fragmentation issues in the SCSI mid-layer's private memory
* allocator. See aic79xx_osm.c ahd_linux_size_nseg() for details.
*/
extern u_int ahd_linux_nseg;
#define AHD_NSEG ahd_linux_nseg
#define AHD_LINUX_MIN_NSEG 64
#else
#define AHD_NSEG 128
#endif
/* /*
* Per-SCB OSM storage. * Per-SCB OSM storage.
...@@ -532,9 +543,7 @@ struct ahd_platform_data { ...@@ -532,9 +543,7 @@ struct ahd_platform_data {
TAILQ_HEAD(, ahd_linux_device) device_runq; TAILQ_HEAD(, ahd_linux_device) device_runq;
struct ahd_completeq completeq; struct ahd_completeq completeq;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
spinlock_t spin_lock; spinlock_t spin_lock;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
struct tasklet_struct runq_tasklet; struct tasklet_struct runq_tasklet;
#endif #endif
...@@ -730,7 +739,6 @@ static __inline void ahd_list_lockinit(void); ...@@ -730,7 +739,6 @@ static __inline void ahd_list_lockinit(void);
static __inline void ahd_list_lock(unsigned long *flags); static __inline void ahd_list_lock(unsigned long *flags);
static __inline void ahd_list_unlock(unsigned long *flags); static __inline void ahd_list_unlock(unsigned long *flags);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
static __inline void static __inline void
ahd_lockinit(struct ahd_softc *ahd) ahd_lockinit(struct ahd_softc *ahd)
{ {
...@@ -818,63 +826,6 @@ ahd_list_unlock(unsigned long *flags) ...@@ -818,63 +826,6 @@ ahd_list_unlock(unsigned long *flags)
spin_unlock_irqrestore(&ahd_list_spinlock, *flags); spin_unlock_irqrestore(&ahd_list_spinlock, *flags);
} }
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */
ahd_lockinit(struct ahd_softc *ahd)
{
}
static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
save_flags(*flags);
cli();
}
static __inline void
ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
restore_flags(*flags);
}
ahd_done_lockinit(struct ahd_softc *ahd)
{
}
static __inline void
ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
{
/*
* The done lock is always held while
* the ahd lock is held so blocking
* interrupts again would have no effect.
*/
}
static __inline void
ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
}
static __inline void
ahd_list_lockinit()
{
}
static __inline void
ahd_list_lock(unsigned long *flags)
{
save_flags(*flags);
cli();
}
static __inline void
ahd_list_unlock(unsigned long *flags)
{
restore_flags(*flags);
}
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) */
/******************************* PCI Definitions ******************************/ /******************************* PCI Definitions ******************************/
/* /*
* PCIM_xxx: mask to locate subfield in register * PCIM_xxx: mask to locate subfield in register
...@@ -945,16 +896,6 @@ void ahd_power_state_change(struct ahd_softc *ahd, ...@@ -945,16 +896,6 @@ void ahd_power_state_change(struct ahd_softc *ahd,
ahd_power_state new_state); ahd_power_state new_state);
/******************************* PCI Routines *********************************/ /******************************* PCI Routines *********************************/
/*
* We need to use the bios32.h routines if we are kernel version 2.1.92 or less.
*/
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
#if defined(__sparc_v9__) || defined(__powerpc__)
#error "PPC and Sparc platforms are only supported under 2.1.92 and above"
#endif
#include <linux/bios32.h>
#endif
int ahd_linux_pci_init(void); int ahd_linux_pci_init(void);
void ahd_linux_pci_exit(void); void ahd_linux_pci_exit(void);
int ahd_pci_map_registers(struct ahd_softc *ahd); int ahd_pci_map_registers(struct ahd_softc *ahd);
...@@ -1270,7 +1211,8 @@ void ahd_platform_set_tags(struct ahd_softc *ahd, ...@@ -1270,7 +1211,8 @@ void ahd_platform_set_tags(struct ahd_softc *ahd,
int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
char channel, int lun, u_int tag, char channel, int lun, u_int tag,
role_t role, uint32_t status); role_t role, uint32_t status);
void ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); AIC_LINUX_IRQRETURN_T
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
void ahd_platform_flushwork(struct ahd_softc *ahd); void ahd_platform_flushwork(struct ahd_softc *ahd);
int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *); int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *);
void ahd_done(struct ahd_softc*, struct scb*); void ahd_done(struct ahd_softc*, struct scb*);
...@@ -1285,5 +1227,5 @@ void ahd_platform_dump_card_state(struct ahd_softc *ahd); ...@@ -1285,5 +1227,5 @@ void ahd_platform_dump_card_state(struct ahd_softc *ahd);
#define AHD_PCI_CONFIG 0 #define AHD_PCI_CONFIG 0
#endif #endif
#define bootverbose aic79xx_verbose #define bootverbose aic79xx_verbose
extern int aic79xx_verbose; extern uint32_t aic79xx_verbose;
#endif /* _AIC79XX_LINUX_H_ */ #endif /* _AIC79XX_LINUX_H_ */
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#70 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#71 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -565,14 +565,13 @@ ahd_check_extport(struct ahd_softc *ahd) ...@@ -565,14 +565,13 @@ ahd_check_extport(struct ahd_softc *ahd)
#if AHD_DEBUG #if AHD_DEBUG
if (have_seeprom != 0 if (have_seeprom != 0
&& (ahd_debug & AHD_DUMP_SEEPROM) != 0) { && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
uint8_t *sc_data; uint16_t *sc_data;
int i; int i;
printf("%s: Seeprom Contents:", ahd_name(ahd)); printf("%s: Seeprom Contents:", ahd_name(ahd));
sc_data = (uint8_t *)sc; sc_data = (uint16_t *)sc;
for (i = 0; i < (sizeof(*sc)); i += 2) for (i = 0; i < (sizeof(*sc)); i += 2)
printf("\n\t0x%.4x", printf("\n\t0x%.4x", sc_data[i]);
sc_data[i] | (sc_data[i+1] << 8));
printf("\n"); printf("\n");
} }
#endif #endif
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr> * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* sym driver. * sym driver.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#14 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#17 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
#include "aic79xx_inline.h" #include "aic79xx_inline.h"
...@@ -173,8 +173,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, ...@@ -173,8 +173,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
tinfo = ahd_fetch_transinfo(ahd, channel, our_id, tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
target_id, &tstate); target_id, &tstate);
copy_info(info, "Channel %c Target %d Negotiation Settings\n", copy_info(info, "Target %d Negotiation Settings\n", target_id);
channel, target_id);
copy_info(info, "\tUser: "); copy_info(info, "\tUser: ");
ahd_format_transinfo(info, &tinfo->user); ahd_format_transinfo(info, &tinfo->user);
targ = ahd->platform_data->targets[target_offset]; targ = ahd->platform_data->targets[target_offset];
...@@ -318,7 +317,11 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset, ...@@ -318,7 +317,11 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset,
AIC79XX_DRIVER_VERSION); AIC79XX_DRIVER_VERSION);
copy_info(&info, "%s\n", ahd->description); copy_info(&info, "%s\n", ahd->description);
ahd_controller_info(ahd, ahd_info); ahd_controller_info(ahd, ahd_info);
copy_info(&info, "%s\n\n", ahd_info); copy_info(&info, "%s\n", ahd_info);
copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
ahd->scb_data.numscbs, AHD_NSEG);
max_targ = 15;
if (ahd->seep_config == NULL) if (ahd->seep_config == NULL)
copy_info(&info, "No Serial EEPROM\n"); copy_info(&info, "No Serial EEPROM\n");
...@@ -335,7 +338,6 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset, ...@@ -335,7 +338,6 @@ ahd_linux_proc_info(char *buffer, char **start, off_t offset,
} }
copy_info(&info, "\n"); copy_info(&info, "\n");
max_targ = 15;
if ((ahd->features & AHD_WIDE) == 0) if ((ahd->features & AHD_WIDE) == 0)
max_targ = 7; max_targ = 7;
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated * DO NOT EDIT - This file is automatically generated
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
*/ */
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry { typedef struct ahd_reg_parse_entry {
...@@ -1923,18 +1923,11 @@ ahd_reg_print_t ahd_longjmp_addr_print; ...@@ -1923,18 +1923,11 @@ ahd_reg_print_t ahd_longjmp_addr_print;
ahd_print_register(NULL, 0, "LONGJMP_ADDR", 0xf8, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "LONGJMP_ADDR", 0xf8, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_longjmp_scb_print;
#else
#define ahd_longjmp_scb_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "LONGJMP_SCB", 0xfa, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_accum_save_print; ahd_reg_print_t ahd_accum_save_print;
#else #else
#define ahd_accum_save_print(regvalue, cur_col, wrap) \ #define ahd_accum_save_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "ACCUM_SAVE", 0xfc, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "ACCUM_SAVE", 0xfa, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
...@@ -2246,59 +2239,45 @@ ahd_reg_print_t ahd_scb_sense_busaddr_print; ...@@ -2246,59 +2239,45 @@ ahd_reg_print_t ahd_scb_sense_busaddr_print;
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_tag_print; ahd_reg_print_t ahd_scb_dataptr_print;
#else
#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_cdb_len_print;
#else
#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x192, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_task_management_print;
#else #else
#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \ #define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x193, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x190, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_next_print; ahd_reg_print_t ahd_scb_datacnt_print;
#else #else
#define ahd_scb_next_print(regvalue, cur_col, wrap) \ #define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT", 0x194, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_DATACNT", 0x198, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_next2_print; ahd_reg_print_t ahd_scb_sgptr_print;
#else #else
#define ahd_scb_next2_print(regvalue, cur_col, wrap) \ #define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_NEXT2", 0x196, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_SGPTR", 0x19c, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_dataptr_print; ahd_reg_print_t ahd_scb_busaddr_print;
#else #else
#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \ #define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a0, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_datacnt_print; ahd_reg_print_t ahd_scb_next_print;
#else #else
#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \ #define ahd_scb_next_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_NEXT", 0x1a4, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_sgptr_print; ahd_reg_print_t ahd_scb_next2_print;
#else #else
#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \ #define ahd_scb_next2_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1a6, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
...@@ -2330,10 +2309,24 @@ ahd_reg_print_t ahd_scb_task_attribute_print; ...@@ -2330,10 +2309,24 @@ ahd_reg_print_t ahd_scb_task_attribute_print;
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_busaddr_print; ahd_reg_print_t ahd_scb_cdb_len_print;
#else #else
#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \ #define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1ac, regvalue, cur_col, wrap) ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x1ac, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_task_management_print;
#else
#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x1ad, regvalue, cur_col, wrap)
#endif
#if AIC_DEBUG_REGISTERS
ahd_reg_print_t ahd_scb_tag_print;
#else
#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
ahd_print_register(NULL, 0, "SCB_TAG", 0x1ae, regvalue, cur_col, wrap)
#endif #endif
#if AIC_DEBUG_REGISTERS #if AIC_DEBUG_REGISTERS
...@@ -2367,6 +2360,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -2367,6 +2360,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SPLTINT 0x01 #define SPLTINT 0x01
#define SEQINTCODE 0x02 #define SEQINTCODE 0x02
#define BAD_SCB_STATUS 0x1a
#define SAW_HWERR 0x19 #define SAW_HWERR 0x19
#define TRACEPOINT3 0x18 #define TRACEPOINT3 0x18
#define TRACEPOINT2 0x17 #define TRACEPOINT2 0x17
...@@ -3508,9 +3502,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3508,9 +3502,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define LONGJMP_ADDR 0xf8 #define LONGJMP_ADDR 0xf8
#define LONGJMP_SCB 0xfa #define ACCUM_SAVE 0xfa
#define ACCUM_SAVE 0xfc
#define WAITING_SCB_TAILS 0x100 #define WAITING_SCB_TAILS 0x100
...@@ -3656,29 +3648,24 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3656,29 +3648,24 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SCB_SENSE_BUSADDR 0x18c #define SCB_SENSE_BUSADDR 0x18c
#define SCB_NEXT_COMPLETE 0x18c #define SCB_NEXT_COMPLETE 0x18c
#define SCB_TAG 0x190 #define SCB_DATAPTR 0x190
#define SCB_CDB_LEN 0x192
#define SCB_CDB_LEN_PTR 0x80
#define SCB_TASK_MANAGEMENT 0x193
#define SCB_NEXT 0x194
#define SCB_NEXT_SCB_BUSADDR 0x194
#define SCB_NEXT2 0x196 #define SCB_DATACNT 0x198
#define SCB_DATAPTR 0x198
#define SCB_DATACNT 0x1a0
#define SG_LAST_SEG 0x80 #define SG_LAST_SEG 0x80
#define SG_HIGH_ADDR_BITS 0x7f #define SG_HIGH_ADDR_BITS 0x7f
#define SCB_SGPTR 0x1a4 #define SCB_SGPTR 0x19c
#define SG_STATUS_VALID 0x04 #define SG_STATUS_VALID 0x04
#define SG_FULL_RESID 0x02 #define SG_FULL_RESID 0x02
#define SG_LIST_NULL 0x01 #define SG_LIST_NULL 0x01
#define SCB_BUSADDR 0x1a0
#define SCB_NEXT 0x1a4
#define SCB_NEXT_SCB_BUSADDR 0x1a4
#define SCB_NEXT2 0x1a6
#define SCB_CONTROL 0x1a8 #define SCB_CONTROL 0x1a8
#define TARGET_SCB 0x80 #define TARGET_SCB 0x80
#define DISCENB 0x40 #define DISCENB 0x40
...@@ -3697,7 +3684,13 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3697,7 +3684,13 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define SCB_TASK_ATTRIBUTE 0x1ab #define SCB_TASK_ATTRIBUTE 0x1ab
#define SCB_BUSADDR 0x1ac #define SCB_CDB_LEN 0x1ac
#define SCB_CDB_LEN_PTR 0x80
#define SCB_TASK_MANAGEMENT 0x1ad
#define SCB_TAG 0x1ae
#define SCB_FIFO_USE_COUNT 0x1ae
#define SCB_SPARE 0x1b0 #define SCB_SPARE 0x1b0
#define SCB_PKT_LUN 0x1b0 #define SCB_PKT_LUN 0x1b0
...@@ -3775,5 +3768,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3775,5 +3768,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */ /* Exported Labels */
#define LABEL_seq_isr 0x26d #define LABEL_seq_isr 0x270
#define LABEL_timer_isr 0x269 #define LABEL_timer_isr 0x26c
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated * DO NOT EDIT - This file is automatically generated
* from the following source files: * from the following source files:
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
...@@ -65,13 +65,14 @@ static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = { ...@@ -65,13 +65,14 @@ static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = {
{ "TRACEPOINT1", 0x16, 0xff }, { "TRACEPOINT1", 0x16, 0xff },
{ "TRACEPOINT2", 0x17, 0xff }, { "TRACEPOINT2", 0x17, 0xff },
{ "TRACEPOINT3", 0x18, 0xff }, { "TRACEPOINT3", 0x18, 0xff },
{ "SAW_HWERR", 0x19, 0xff } { "SAW_HWERR", 0x19, 0xff },
{ "BAD_SCB_STATUS", 0x1a, 0xff }
}; };
int int
ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SEQINTCODE_parse_table, 26, "SEQINTCODE", return (ahd_print_register(SEQINTCODE_parse_table, 27, "SEQINTCODE",
0x02, regvalue, cur_col, wrap)); 0x02, regvalue, cur_col, wrap));
} }
...@@ -3097,18 +3098,11 @@ ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -3097,18 +3098,11 @@ ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
0xf8, regvalue, cur_col, wrap)); 0xf8, regvalue, cur_col, wrap));
} }
int
ahd_longjmp_scb_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "LONGJMP_SCB",
0xfa, regvalue, cur_col, wrap));
}
int int
ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "ACCUM_SAVE", return (ahd_print_register(NULL, 0, "ACCUM_SAVE",
0xfc, regvalue, cur_col, wrap)); 0xfa, regvalue, cur_col, wrap));
} }
int int
...@@ -3491,50 +3485,11 @@ ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -3491,50 +3485,11 @@ ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
0x18c, regvalue, cur_col, wrap)); 0x18c, regvalue, cur_col, wrap));
} }
int
ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_TAG",
0x190, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
{ "SCB_CDB_LEN_PTR", 0x80, 0x80 }
};
int
ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN",
0x192, regvalue, cur_col, wrap));
}
int
ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
0x193, regvalue, cur_col, wrap));
}
int
ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT",
0x194, regvalue, cur_col, wrap));
}
int
ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT2",
0x196, regvalue, cur_col, wrap));
}
int int
ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "SCB_DATAPTR", return (ahd_print_register(NULL, 0, "SCB_DATAPTR",
0x198, regvalue, cur_col, wrap)); 0x190, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = { static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
...@@ -3546,7 +3501,7 @@ int ...@@ -3546,7 +3501,7 @@ int
ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT", return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
0x1a0, regvalue, cur_col, wrap)); 0x198, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = { static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
...@@ -3559,9 +3514,30 @@ int ...@@ -3559,9 +3514,30 @@ int
ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR", return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
0x19c, regvalue, cur_col, wrap));
}
int
ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
0x1a0, regvalue, cur_col, wrap));
}
int
ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT",
0x1a4, regvalue, cur_col, wrap)); 0x1a4, regvalue, cur_col, wrap));
} }
int
ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_NEXT2",
0x1a6, regvalue, cur_col, wrap));
}
static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = { static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
{ "SCB_TAG_TYPE", 0x03, 0x03 }, { "SCB_TAG_TYPE", 0x03, 0x03 },
{ "DISCONNECTED", 0x04, 0x04 }, { "DISCONNECTED", 0x04, 0x04 },
...@@ -3609,13 +3585,31 @@ ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap) ...@@ -3609,13 +3585,31 @@ ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap)
0x1ab, regvalue, cur_col, wrap)); 0x1ab, regvalue, cur_col, wrap));
} }
static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
{ "SCB_CDB_LEN_PTR", 0x80, 0x80 }
};
int int
ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
return (ahd_print_register(NULL, 0, "SCB_BUSADDR", return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN",
0x1ac, regvalue, cur_col, wrap)); 0x1ac, regvalue, cur_col, wrap));
} }
int
ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
0x1ad, regvalue, cur_col, wrap));
}
int
ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
{
return (ahd_print_register(NULL, 0, "SCB_TAG",
0x1ae, regvalue, cur_col, wrap));
}
int int
ahd_scb_spare_print(u_int regvalue, u_int *cur_col, u_int wrap) ahd_scb_spare_print(u_int regvalue, u_int *cur_col, u_int wrap)
{ {
......
This diff is collapsed.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#74 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#75 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -1082,6 +1082,14 @@ struct ahc_softc { ...@@ -1082,6 +1082,14 @@ struct ahc_softc {
/* PCI cacheline size. */ /* PCI cacheline size. */
u_int pci_cachesize; u_int pci_cachesize;
/*
* Count of parity errors we have seen as a target.
* We auto-disable parity error checking after seeing
* AHC_PCI_TARGET_PERR_THRESH number of errors.
*/
u_int pci_target_perr_count;
#define AHC_PCI_TARGET_PERR_THRESH 10
/* Maximum number of sequencer instructions supported. */ /* Maximum number of sequencer instructions supported. */
u_int instruction_ram_size; u_int instruction_ram_size;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#124 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#128 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -3949,7 +3949,6 @@ ahc_free(struct ahc_softc *ahc) ...@@ -3949,7 +3949,6 @@ ahc_free(struct ahc_softc *ahc)
{ {
int i; int i;
ahc_fini_scbdata(ahc);
switch (ahc->init_level) { switch (ahc->init_level) {
default: default:
case 5: case 5:
...@@ -3981,6 +3980,7 @@ ahc_free(struct ahc_softc *ahc) ...@@ -3981,6 +3980,7 @@ ahc_free(struct ahc_softc *ahc)
ahc_dma_tag_destroy(ahc, ahc->parent_dmat); ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
#endif #endif
ahc_platform_free(ahc); ahc_platform_free(ahc);
ahc_fini_scbdata(ahc);
for (i = 0; i < AHC_NUM_TARGETS; i++) { for (i = 0; i < AHC_NUM_TARGETS; i++) {
struct ahc_tmode_tstate *tstate; struct ahc_tmode_tstate *tstate;
...@@ -5100,7 +5100,7 @@ ahc_pause_and_flushwork(struct ahc_softc *ahc) ...@@ -5100,7 +5100,7 @@ ahc_pause_and_flushwork(struct ahc_softc *ahc)
} while (--maxloops } while (--maxloops
&& (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0) && (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0)
&& ((intstat & INT_PEND) != 0 && ((intstat & INT_PEND) != 0
|| (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)))); || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)) != 0));
if (maxloops == 0) { if (maxloops == 0) {
printf("Infinite interrupt loop, INTSTAT = %x", printf("Infinite interrupt loop, INTSTAT = %x",
ahc_inb(ahc, INTSTAT)); ahc_inb(ahc, INTSTAT));
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#40 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#42 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -500,7 +500,7 @@ ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb) ...@@ -500,7 +500,7 @@ ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb)
static __inline void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op); static __inline void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op);
static __inline void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op); static __inline void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op);
static __inline u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc); static __inline u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc);
static __inline void ahc_intr(struct ahc_softc *ahc); static __inline int ahc_intr(struct ahc_softc *ahc);
static __inline void static __inline void
ahc_sync_qoutfifo(struct ahc_softc *ahc, int op) ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)
...@@ -558,7 +558,7 @@ ahc_check_cmdcmpltqueues(struct ahc_softc *ahc) ...@@ -558,7 +558,7 @@ ahc_check_cmdcmpltqueues(struct ahc_softc *ahc)
/* /*
* Catch an interrupt from the adapter * Catch an interrupt from the adapter
*/ */
static __inline void static __inline int
ahc_intr(struct ahc_softc *ahc) ahc_intr(struct ahc_softc *ahc)
{ {
u_int intstat; u_int intstat;
...@@ -570,7 +570,7 @@ ahc_intr(struct ahc_softc *ahc) ...@@ -570,7 +570,7 @@ ahc_intr(struct ahc_softc *ahc)
* so just return. This is likely just a shared * so just return. This is likely just a shared
* interrupt. * interrupt.
*/ */
return; return (0);
} }
/* /*
* Instead of directly reading the interrupt status register, * Instead of directly reading the interrupt status register,
...@@ -585,6 +585,20 @@ ahc_intr(struct ahc_softc *ahc) ...@@ -585,6 +585,20 @@ ahc_intr(struct ahc_softc *ahc)
intstat = ahc_inb(ahc, INTSTAT); intstat = ahc_inb(ahc, INTSTAT);
} }
if ((intstat & INT_PEND) == 0) {
#if AHC_PCI_CONFIG > 0
if (ahc->unsolicited_ints > 500) {
ahc->unsolicited_ints = 0;
if ((ahc->chip & AHC_PCI) != 0
&& (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
ahc->bus_intr(ahc);
}
#endif
ahc->unsolicited_ints++;
return (0);
}
ahc->unsolicited_ints = 0;
if (intstat & CMDCMPLT) { if (intstat & CMDCMPLT) {
ahc_outb(ahc, CLRINT, CLRCMDINT); ahc_outb(ahc, CLRINT, CLRCMDINT);
...@@ -604,38 +618,25 @@ ahc_intr(struct ahc_softc *ahc) ...@@ -604,38 +618,25 @@ ahc_intr(struct ahc_softc *ahc)
#endif #endif
} }
if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) /*
/* Hot eject */ * Handle statuses that may invalidate our cached
return; * copy of INTSTAT separately.
*/
if ((intstat & INT_PEND) == 0) { if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) {
#if AHC_PCI_CONFIG > 0 /* Hot eject. Do nothing */
if (ahc->unsolicited_ints > 500) { } else if (intstat & BRKADRINT) {
ahc->unsolicited_ints = 0;
if ((ahc->chip & AHC_PCI) != 0
&& (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
ahc->bus_intr(ahc);
}
#endif
ahc->unsolicited_ints++;
return;
}
ahc->unsolicited_ints = 0;
if (intstat & BRKADRINT) {
ahc_handle_brkadrint(ahc); ahc_handle_brkadrint(ahc);
/* Fatal error, no more interrupts to handle. */ } else if ((intstat & (SEQINT|SCSIINT)) != 0) {
return;
}
if ((intstat & (SEQINT|SCSIINT)) != 0)
ahc_pause_bug_fix(ahc); ahc_pause_bug_fix(ahc);
if ((intstat & SEQINT) != 0) if ((intstat & SEQINT) != 0)
ahc_handle_seqint(ahc, intstat); ahc_handle_seqint(ahc, intstat);
if ((intstat & SCSIINT) != 0) if ((intstat & SCSIINT) != 0)
ahc_handle_scsiint(ahc, intstat); ahc_handle_scsiint(ahc, intstat);
}
return (1);
} }
#endif /* _AIC7XXX_INLINE_H_ */ #endif /* _AIC7XXX_INLINE_H_ */
This diff is collapsed.
This diff is collapsed.
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#62 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#63 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -837,14 +837,6 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -837,14 +837,6 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
command |= PCIM_CMD_BUSMASTEREN; command |= PCIM_CMD_BUSMASTEREN;
/*
* Disable PCI parity error reporting. Users typically
* do this to work around broken PCI chipsets that get
* the parity timing wrong and thus generate lots of spurious
* errors.
*/
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
command &= ~PCIM_CMD_PERRESPEN;
ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
/* On all PCI adapters, we allow SCB paging */ /* On all PCI adapters, we allow SCB paging */
...@@ -854,6 +846,19 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ...@@ -854,6 +846,19 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
if (error != 0) if (error != 0)
return (error); return (error);
/*
* Disable PCI parity error checking. Users typically
* do this to work around broken PCI chipsets that get
* the parity timing wrong and thus generate lots of spurious
* errors. The chip only allows us to disable *all* parity
* error reporting when doing this, so CIO bus, scb ram, and
* scratch ram parity errors will be ignored too.
*/
if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) {
ahc->pause |= FAILDIS;
ahc->unpause |= FAILDIS;
}
ahc->bus_intr = ahc_pci_intr; ahc->bus_intr = ahc_pci_intr;
ahc->bus_chip_init = ahc_pci_chip_init; ahc->bus_chip_init = ahc_pci_chip_init;
ahc->bus_suspend = ahc_pci_suspend; ahc->bus_suspend = ahc_pci_suspend;
...@@ -1998,6 +2003,7 @@ ahc_pci_intr(struct ahc_softc *ahc) ...@@ -1998,6 +2003,7 @@ ahc_pci_intr(struct ahc_softc *ahc)
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
if (status1 & DPE) { if (status1 & DPE) {
ahc->pci_target_perr_count++;
printf("%s: Data Parity Error Detected during address " printf("%s: Data Parity Error Detected during address "
"or write data phase\n", ahc_name(ahc)); "or write data phase\n", ahc_name(ahc));
} }
...@@ -2029,6 +2035,19 @@ ahc_pci_intr(struct ahc_softc *ahc) ...@@ -2029,6 +2035,19 @@ ahc_pci_intr(struct ahc_softc *ahc)
ahc_outb(ahc, CLRINT, CLRPARERR); ahc_outb(ahc, CLRINT, CLRPARERR);
} }
if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
printf(
"%s: WARNING WARNING WARNING WARNING\n"
"%s: Too many PCI parity errors observed as a target.\n"
"%s: Some device on this bus is generating bad parity.\n"
"%s: This is an error *observed by*, not *generated by*, this controller.\n"
"%s: PCI parity error checking has been disabled.\n"
"%s: WARNING WARNING WARNING WARNING\n",
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
ahc->pause |= FAILDIS;
ahc->unpause |= FAILDIS;
}
ahc_unpause(ahc); ahc_unpause(ahc);
} }
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr> * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* sym driver. * sym driver.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#24 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#27 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
#include "aic7xxx_inline.h" #include "aic7xxx_inline.h"
...@@ -148,8 +148,9 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, ...@@ -148,8 +148,9 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
tinfo = ahc_fetch_transinfo(ahc, channel, our_id, tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
target_id, &tstate); target_id, &tstate);
copy_info(info, "Channel %c Target %d Negotiation Settings\n", if ((ahc->features & AHC_TWIN) != 0)
channel, target_id); copy_info(info, "Channel %c ", channel);
copy_info(info, "Target %d Negotiation Settings\n", target_id);
copy_info(info, "\tUser: "); copy_info(info, "\tUser: ");
ahc_format_transinfo(info, &tinfo->user); ahc_format_transinfo(info, &tinfo->user);
targ = ahc->platform_data->targets[target_offset]; targ = ahc->platform_data->targets[target_offset];
...@@ -327,7 +328,10 @@ ahc_linux_proc_info(char *buffer, char **start, off_t offset, ...@@ -327,7 +328,10 @@ ahc_linux_proc_info(char *buffer, char **start, off_t offset,
AIC7XXX_DRIVER_VERSION); AIC7XXX_DRIVER_VERSION);
copy_info(&info, "%s\n", ahc->description); copy_info(&info, "%s\n", ahc->description);
ahc_controller_info(ahc, ahc_info); ahc_controller_info(ahc, ahc_info);
copy_info(&info, "%s\n\n", ahc_info); copy_info(&info, "%s\n", ahc_info);
copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
ahc->scb_data->numscbs, AHC_NSEG);
if (ahc->seep_config == NULL) if (ahc->seep_config == NULL)
copy_info(&info, "No Serial EEPROM\n"); copy_info(&info, "No Serial EEPROM\n");
......
...@@ -1335,7 +1335,7 @@ aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data, ...@@ -1335,7 +1335,7 @@ aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data,
char * char *
aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
aic_option_callback_t *callback, void *callback_arg) aic_option_callback_t *callback, u_long callback_arg)
{ {
char *tok_end; char *tok_end;
char *tok_end2; char *tok_end2;
......
This diff is collapsed.
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