Commit 80e044ad authored by Justin T. Gibbs's avatar Justin T. Gibbs

Aic79XX Driver Update [Rev 1.3.5]

 o Clean up driver locking by making the locking semantics between
   2.4.X and 2.5.X almost identical.  Take advantage of SCSI_HAS_HOST_LOCK
   in certain RedHat kernels.
 o Clean up command line parsing.
 o Fix module unload/reload issues stemming from DV thread teardown
   and a missing deregistration of our reboot notifier (lost during
   PCI hot plug integration).
 o Correct precompensation value used for U320 transfers on
   rev A4 hardware.
 o Extract VPD information from the seeprom for potential use
   in sorting controller probes to match boot order.
 o Make LED activity more visible on Rev A4 hardware.
parent dfb4b108
...@@ -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#86 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#88 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -322,7 +322,11 @@ typedef enum { ...@@ -322,7 +322,11 @@ typedef enum {
* glitches. This flag tells the firmware to tolerate * glitches. This flag tells the firmware to tolerate
* early REQ assertions. * early REQ assertions.
*/ */
AHD_EARLY_REQ_BUG = 0x400000 AHD_EARLY_REQ_BUG = 0x400000,
/*
* The LED does not stay on long enough in packetized modes.
*/
AHD_FAINT_LED_BUG = 0x800000
} ahd_bug; } ahd_bug;
/* /*
...@@ -332,10 +336,7 @@ typedef enum { ...@@ -332,10 +336,7 @@ typedef enum {
*/ */
typedef enum { typedef enum {
AHD_FNONE = 0x00000, AHD_FNONE = 0x00000,
AHD_PRIMARY_CHANNEL = 0x00003,/* AHD_BOOT_CHANNEL = 0x00001,/* We were set as the boot channel. */
* The channel that should
* be probed first.
*/
AHD_USEDEFAULTS = 0x00004,/* AHD_USEDEFAULTS = 0x00004,/*
* For cards without an seeprom * For cards without an seeprom
* or a BIOS to initialize the chip's * or a BIOS to initialize the chip's
...@@ -900,6 +901,40 @@ struct seeprom_config { ...@@ -900,6 +901,40 @@ struct seeprom_config {
uint16_t checksum; /* word 31 */ uint16_t checksum; /* word 31 */
}; };
/*
* Vital Product Data used during POST and by the BIOS.
*/
struct vpd_config {
uint8_t bios_flags;
#define VPDMASTERBIOS 0x0001
#define VPDBOOTHOST 0x0002
uint8_t reserved_1[21];
uint8_t resource_type;
uint8_t resource_len[2];
uint8_t resource_data[8];
uint8_t vpd_tag;
uint16_t vpd_len;
uint8_t vpd_keyword[2];
uint8_t length;
uint8_t revision;
uint8_t device_flags;
uint8_t termnation_menus[2];
uint8_t fifo_threshold;
uint8_t end_tag;
uint8_t vpd_checksum;
uint16_t default_target_flags;
uint16_t default_bios_flags;
uint16_t default_ctrl_flags;
uint8_t default_irq;
uint8_t pci_lattime;
uint8_t max_target;
uint8_t boot_lun;
uint16_t signature;
uint8_t reserved_2;
uint8_t checksum;
uint8_t reserved_3[4];
};
/****************************** Flexport Logic ********************************/ /****************************** Flexport Logic ********************************/
#define FLXADDR_TERMCTL 0x0 #define FLXADDR_TERMCTL 0x0
#define FLX_TERMCTL_ENSECHIGH 0x8 #define FLX_TERMCTL_ENSECHIGH 0x8
...@@ -932,11 +967,12 @@ struct seeprom_config { ...@@ -932,11 +967,12 @@ struct seeprom_config {
#define FLX_CSTAT_INVALID 0x3 #define FLX_CSTAT_INVALID 0x3
int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count); u_int start_addr, u_int count, int bstream);
int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count); u_int start_addr, u_int count);
int ahd_wait_seeprom(struct ahd_softc *ahd); int ahd_wait_seeprom(struct ahd_softc *ahd);
int ahd_verify_vpd_cksum(struct vpd_config *vpd);
int ahd_verify_cksum(struct seeprom_config *sc); int ahd_verify_cksum(struct seeprom_config *sc);
int ahd_acquire_seeprom(struct ahd_softc *ahd); int ahd_acquire_seeprom(struct ahd_softc *ahd);
void ahd_release_seeprom(struct ahd_softc *ahd); void ahd_release_seeprom(struct ahd_softc *ahd);
...@@ -1321,6 +1357,8 @@ int ahd_softc_init(struct ahd_softc *); ...@@ -1321,6 +1357,8 @@ int ahd_softc_init(struct ahd_softc *);
void ahd_controller_info(struct ahd_softc *ahd, char *buf); void ahd_controller_info(struct ahd_softc *ahd, char *buf);
int ahd_init(struct ahd_softc *ahd); int ahd_init(struct ahd_softc *ahd);
int ahd_default_config(struct ahd_softc *ahd); int ahd_default_config(struct ahd_softc *ahd);
int ahd_parse_vpddata(struct ahd_softc *ahd,
struct vpd_config *vpd);
int ahd_parse_cfgdata(struct ahd_softc *ahd, int ahd_parse_cfgdata(struct ahd_softc *ahd,
struct seeprom_config *sc); struct seeprom_config *sc);
void ahd_intr_enable(struct ahd_softc *ahd, int enable); void ahd_intr_enable(struct ahd_softc *ahd, int enable);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#64 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $"
/* /*
* 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
...@@ -2545,10 +2545,10 @@ const AHD_PRECOMP_CUTBACK_37 0x07 ...@@ -2545,10 +2545,10 @@ const AHD_PRECOMP_CUTBACK_37 0x07
const AHD_SLEWRATE_MASK 0x78 const AHD_SLEWRATE_MASK 0x78
const AHD_SLEWRATE_SHIFT 3 const AHD_SLEWRATE_SHIFT 3
/* /*
* Rev A has only a single bit of slew adjustment. * Rev A has only a single bit (high bit of field) of slew adjustment.
* Rev B has 4 bits. * Rev B has 4 bits. The current default happens to be the same for both.
*/ */
const AHD_SLEWRATE_DEF_REVA 0x01 const AHD_SLEWRATE_DEF_REVA 0x08
const AHD_SLEWRATE_DEF_REVB 0x08 const AHD_SLEWRATE_DEF_REVB 0x08
/* Rev A does not have any amplitude setting. */ /* Rev A does not have any amplitude setting. */
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#88 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd" PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_" PREFIX = "ahd_"
...@@ -89,6 +89,13 @@ END_CRITICAL; ...@@ -89,6 +89,13 @@ END_CRITICAL;
idle_loop_check_nonpackreq: idle_loop_check_nonpackreq:
test SSTAT2, NONPACKREQ jz . + 2; test SSTAT2, NONPACKREQ jz . + 2;
call unexpected_nonpkt_phase_find_ctxt; call unexpected_nonpkt_phase_find_ctxt;
if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
and A, FIFO0FREE|FIFO1FREE, DFFSTAT;
cmp A, FIFO0FREE|FIFO1FREE jne . + 3;
and SBLKCTL, ~DIAGLEDEN|DIAGLEDON;
jmp . + 2;
or SBLKCTL, DIAGLEDEN|DIAGLEDON;
}
call idle_loop_gsfifo_in_scsi_mode; call idle_loop_gsfifo_in_scsi_mode;
call idle_loop_service_fifos; call idle_loop_service_fifos;
call idle_loop_cchan; call idle_loop_cchan;
......
...@@ -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#174 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#178 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -4832,9 +4832,6 @@ ahd_softc_insert(struct ahd_softc *ahd) ...@@ -4832,9 +4832,6 @@ ahd_softc_insert(struct ahd_softc *ahd)
slave->flags &= ~AHD_BIOS_ENABLED; slave->flags &= ~AHD_BIOS_ENABLED;
slave->flags |= slave->flags |=
master->flags & AHD_BIOS_ENABLED; master->flags & AHD_BIOS_ENABLED;
slave->flags &= ~AHD_PRIMARY_CHANNEL;
slave->flags |=
master->flags & AHD_PRIMARY_CHANNEL;
break; break;
} }
} }
...@@ -4846,7 +4843,7 @@ ahd_softc_insert(struct ahd_softc *ahd) ...@@ -4846,7 +4843,7 @@ ahd_softc_insert(struct ahd_softc *ahd)
*/ */
list_ahd = TAILQ_FIRST(&ahd_tailq); list_ahd = TAILQ_FIRST(&ahd_tailq);
while (list_ahd != NULL while (list_ahd != NULL
&& ahd_softc_comp(list_ahd, ahd) <= 0) && ahd_softc_comp(ahd, list_ahd) <= 0)
list_ahd = TAILQ_NEXT(list_ahd, links); list_ahd = TAILQ_NEXT(list_ahd, links);
if (list_ahd != NULL) if (list_ahd != NULL)
TAILQ_INSERT_BEFORE(list_ahd, ahd, links); TAILQ_INSERT_BEFORE(list_ahd, ahd, links);
...@@ -6535,6 +6532,22 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc) ...@@ -6535,6 +6532,22 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
return (0); return (0);
} }
/*
* Parse device configuration information.
*/
int
ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
{
int error;
error = ahd_verify_vpd_cksum(vpd);
if (error == 0)
return (EINVAL);
if ((vpd->bios_flags & VPDBOOTHOST) != 0)
ahd->flags |= AHD_BOOT_CHANNEL;
return (0);
}
void void
ahd_intr_enable(struct ahd_softc *ahd, int enable) ahd_intr_enable(struct ahd_softc *ahd, int enable)
{ {
...@@ -6815,7 +6828,6 @@ ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) ...@@ -6815,7 +6828,6 @@ ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
/* /*
* Return the untagged transaction id for a given target/channel lun. * Return the untagged transaction id for a given target/channel lun.
* Optionally, clear the entry.
*/ */
u_int u_int
ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
...@@ -7325,7 +7337,6 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, ...@@ -7325,7 +7337,6 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
{ {
struct scb *scbp; struct scb *scbp;
struct scb *scbp_next; struct scb *scbp_next;
u_int active_scb;
u_int i, j; u_int i, j;
u_int maxtarget; u_int maxtarget;
u_int minlun; u_int minlun;
...@@ -7333,11 +7344,10 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, ...@@ -7333,11 +7344,10 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
int found; int found;
ahd_mode_state saved_modes; ahd_mode_state saved_modes;
/* restore these when we're done */ /* restore this when we're done */
active_scb = ahd_get_scbptr(ahd);
saved_modes = ahd_save_modes(ahd); saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL, found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
role, CAM_REQUEUE_REQ, SEARCH_COMPLETE); role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
...@@ -7411,7 +7421,6 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, ...@@ -7411,7 +7421,6 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
found++; found++;
} }
} }
ahd_set_scbptr(ahd, active_scb);
ahd_restore_modes(ahd, saved_modes); ahd_restore_modes(ahd, saved_modes);
ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status); ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
ahd->flags |= AHD_UPDATE_PEND_CMDS; ahd->flags |= AHD_UPDATE_PEND_CMDS;
...@@ -8772,11 +8781,12 @@ ahd_dump_scbs(struct ahd_softc *ahd) ...@@ -8772,11 +8781,12 @@ ahd_dump_scbs(struct ahd_softc *ahd)
/* /*
* Read count 16bit words from 16bit word address start_addr from the * Read count 16bit words from 16bit word address start_addr from the
* SEEPROM attached to the controller, into buf, using the controller's * SEEPROM attached to the controller, into buf, using the controller's
* SEEPROM reading state machine. * SEEPROM reading state machine. Optionally treat the data as a byte
* stream in terms of byte order.
*/ */
int int
ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count) u_int start_addr, u_int count, int bytestream)
{ {
u_int cur_addr; u_int cur_addr;
u_int end_addr; u_int end_addr;
...@@ -8790,13 +8800,26 @@ ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, ...@@ -8790,13 +8800,26 @@ ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
end_addr = start_addr + count; end_addr = start_addr + count;
for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) { for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
ahd_outb(ahd, SEEADR, cur_addr); ahd_outb(ahd, SEEADR, cur_addr);
ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART); ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
error = ahd_wait_seeprom(ahd); error = ahd_wait_seeprom(ahd);
if (error) if (error)
break; break;
*buf++ = ahd_inw(ahd, SEEDAT); if (bytestream != 0) {
uint8_t *bytestream_ptr;
bytestream_ptr = (uint8_t *)buf;
*bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
*bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
} else {
/*
* ahd_inw() already handles machine byte order.
*/
*buf = ahd_inw(ahd, SEEDAT);
}
buf++;
} }
return (error); return (error);
} }
...@@ -8869,6 +8892,38 @@ ahd_wait_seeprom(struct ahd_softc *ahd) ...@@ -8869,6 +8892,38 @@ ahd_wait_seeprom(struct ahd_softc *ahd)
return (0); return (0);
} }
/*
* Validate the two checksums in the per_channel
* vital product data struct.
*/
int
ahd_verify_vpd_cksum(struct vpd_config *vpd)
{
int i;
int maxaddr;
uint32_t checksum;
uint8_t *vpdarray;
vpdarray = (uint8_t *)vpd;
maxaddr = offsetof(struct vpd_config, vpd_checksum);
checksum = 0;
for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
checksum = checksum + vpdarray[i];
if (checksum == 0
|| (-checksum & 0xFF) != vpd->vpd_checksum)
return (0);
checksum = 0;
maxaddr = offsetof(struct vpd_config, checksum);
for (i = offsetof(struct vpd_config, default_target_flags);
i < maxaddr; i++)
checksum = checksum + vpdarray[i];
if (checksum == 0
|| (-checksum & 0xFF) != vpd->checksum)
return (0);
return (1);
}
int int
ahd_verify_cksum(struct seeprom_config *sc) ahd_verify_cksum(struct seeprom_config *sc)
{ {
......
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#118 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#121 $
* *
*/ */
#ifndef _AIC79XX_LINUX_H_ #ifndef _AIC79XX_LINUX_H_
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
* Compile in debugging code, but do not enable any printfs. * Compile in debugging code, but do not enable any printfs.
*/ */
#define AHD_DEBUG 1 #define AHD_DEBUG 1
#define AHD_DEBUG_OPTS 0
#endif #endif
/* No debugging code. */ /* No debugging code. */
#endif #endif
...@@ -286,7 +287,13 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -286,7 +287,13 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h> #include <linux/smp.h>
#endif #endif
#define AIC79XX_DRIVER_VERSION "1.3.4" #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
#define AHD_SCSI_HAS_HOST_LOCK 1
#else
#define AHD_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC79XX_DRIVER_VERSION "1.3.5"
/**************************** Front End Queues ********************************/ /**************************** Front End Queues ********************************/
/* /*
...@@ -733,7 +740,6 @@ ahd_lockinit(struct ahd_softc *ahd) ...@@ -733,7 +740,6 @@ ahd_lockinit(struct ahd_softc *ahd)
static __inline void static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags) ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{ {
*flags = 0;
spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags); spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
} }
...@@ -747,23 +753,24 @@ static __inline void ...@@ -747,23 +753,24 @@ static __inline void
ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags) ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags)
{ {
/* /*
* In 2.5.X, the midlayer takes our lock just before * In 2.5.X and some 2.4.X versions, the midlayer takes our
* calling us, so avoid locking again. * lock just before calling us, so we avoid locking again.
* For other kernel versions, the io_request_lock is taken
* just before our entry point is called. In this case, we
* trade the io_request_lock for our per-softc lock.
*/ */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #if AHD_SCSI_HAS_HOST_LOCK == 0
ahd_lock(ahd, flags); spin_unlock(&io_request_lock);
spin_lock(&ahd->platform_data->spin_lock);
#endif #endif
} }
static __inline void static __inline void
ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags) ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags)
{ {
/* #if AHD_SCSI_HAS_HOST_LOCK == 0
* In 2.5.X, the midlayer takes our lock just before spin_unlock(&ahd->platform_data->spin_lock);
* calling us and unlocks when we return, so let it do the unlock. spin_lock(&io_request_lock);
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, flags);
#endif #endif
} }
...@@ -780,17 +787,16 @@ ahd_done_lockinit(struct ahd_softc *ahd) ...@@ -780,17 +787,16 @@ ahd_done_lockinit(struct ahd_softc *ahd)
static __inline void static __inline void
ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
{ {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #if AHD_SCSI_HAS_HOST_LOCK == 0
*flags = 0; spin_lock(&io_request_lock);
spin_lock_irqsave(&io_request_lock, *flags);
#endif #endif
} }
static __inline void static __inline void
ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
{ {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock_irqrestore(&io_request_lock, *flags); spin_unlock(&io_request_lock);
#endif #endif
} }
...@@ -803,7 +809,6 @@ ahd_list_lockinit() ...@@ -803,7 +809,6 @@ ahd_list_lockinit()
static __inline void static __inline void
ahd_list_lock(unsigned long *flags) ahd_list_lock(unsigned long *flags)
{ {
*flags = 0;
spin_lock_irqsave(&ahd_list_spinlock, *flags); spin_lock_irqsave(&ahd_list_spinlock, *flags);
} }
...@@ -822,7 +827,6 @@ ahd_lockinit(struct ahd_softc *ahd) ...@@ -822,7 +827,6 @@ ahd_lockinit(struct ahd_softc *ahd)
static __inline void static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags) ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{ {
*flags = 0;
save_flags(*flags); save_flags(*flags);
cli(); cli();
} }
...@@ -860,7 +864,6 @@ ahd_list_lockinit() ...@@ -860,7 +864,6 @@ ahd_list_lockinit()
static __inline void static __inline void
ahd_list_lock(unsigned long *flags) ahd_list_lock(unsigned long *flags)
{ {
*flags = 0;
save_flags(*flags); save_flags(*flags);
cli(); cli();
} }
......
...@@ -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#67 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#70 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -466,6 +466,7 @@ ahd_pci_test_register_access(struct ahd_softc *ahd) ...@@ -466,6 +466,7 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
static int static int
ahd_check_extport(struct ahd_softc *ahd) ahd_check_extport(struct ahd_softc *ahd)
{ {
struct vpd_config vpd;
struct seeprom_config *sc; struct seeprom_config *sc;
u_int adapter_control; u_int adapter_control;
int have_seeprom; int have_seeprom;
...@@ -476,6 +477,27 @@ ahd_check_extport(struct ahd_softc *ahd) ...@@ -476,6 +477,27 @@ ahd_check_extport(struct ahd_softc *ahd)
if (have_seeprom) { if (have_seeprom) {
u_int start_addr; u_int start_addr;
/*
* Fetch VPD for this function and parse it.
*/
if (bootverbose)
printf("%s: Reading VPD from SEEPROM...",
ahd_name(ahd));
/* Address is always in units of 16bit words */
start_addr = ((2 * sizeof(*sc))
+ (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
start_addr, sizeof(vpd)/2,
/*bytestream*/TRUE);
if (error == 0)
error = ahd_parse_vpddata(ahd, &vpd);
if (bootverbose)
printf("%s: VPD parsing %s\n",
ahd_name(ahd),
error == 0 ? "successful" : "failed");
if (bootverbose) if (bootverbose)
printf("%s: Reading SEEPROM...", ahd_name(ahd)); printf("%s: Reading SEEPROM...", ahd_name(ahd));
...@@ -483,7 +505,8 @@ ahd_check_extport(struct ahd_softc *ahd) ...@@ -483,7 +505,8 @@ ahd_check_extport(struct ahd_softc *ahd)
start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A'); start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
error = ahd_read_seeprom(ahd, (uint16_t *)sc, error = ahd_read_seeprom(ahd, (uint16_t *)sc,
start_addr, sizeof(*sc)/2); start_addr, sizeof(*sc)/2,
/*bytestream*/FALSE);
if (error != 0) { if (error != 0) {
printf("Unable to read SEEPROM\n"); printf("Unable to read SEEPROM\n");
...@@ -803,7 +826,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) ...@@ -803,7 +826,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
/* Clear latched errors. So our interrupt deasserts. */ /* Clear latched errors. So our interrupt deasserts. */
ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]); ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]); ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
if (i != 0) if (i > 1)
continue; continue;
sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0); sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1); sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
...@@ -825,7 +848,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) ...@@ -825,7 +848,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
split_status_source[i]); split_status_source[i]);
} }
if (i != 0) if (i > 1)
continue; continue;
if ((sg_split_status[i] & (0x1 << bit)) != 0) { if ((sg_split_status[i] & (0x1 << bit)) != 0) {
...@@ -887,7 +910,8 @@ ahd_aic7902_setup(struct ahd_softc *ahd) ...@@ -887,7 +910,8 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
| AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
| AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
| AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
| AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG; | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
| AHD_FAINT_LED_BUG;
/* /*
* IO Cell paramter setup. * IO Cell paramter setup.
......
...@@ -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#13 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#14 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
#include "aic79xx_inline.h" #include "aic79xx_inline.h"
...@@ -262,7 +262,8 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length) ...@@ -262,7 +262,8 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr, ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr,
sizeof(struct seeprom_config)/2); sizeof(struct seeprom_config)/2);
ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config, ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config,
start_addr, sizeof(struct seeprom_config)/2); start_addr, sizeof(struct seeprom_config)/2,
/*ByteStream*/FALSE);
ahd_release_seeprom(ahd); ahd_release_seeprom(ahd);
written = length; written = length;
} }
......
...@@ -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#87 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/ */
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 {
...@@ -3720,7 +3720,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3720,7 +3720,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define AHD_AMPLITUDE_SHIFT 0x00 #define AHD_AMPLITUDE_SHIFT 0x00
#define AHD_AMPLITUDE_MASK 0x07 #define AHD_AMPLITUDE_MASK 0x07
#define AHD_ANNEXCOL_AMPLITUDE 0x06 #define AHD_ANNEXCOL_AMPLITUDE 0x06
#define AHD_SLEWRATE_DEF_REVA 0x01 #define AHD_SLEWRATE_DEF_REVA 0x08
#define AHD_SLEWRATE_SHIFT 0x03 #define AHD_SLEWRATE_SHIFT 0x03
#define AHD_SLEWRATE_MASK 0x78 #define AHD_SLEWRATE_MASK 0x78
#define AHD_PRECOMP_CUTBACK_29 0x06 #define AHD_PRECOMP_CUTBACK_29 0x06
...@@ -3775,5 +3775,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print; ...@@ -3775,5 +3775,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */ /* Exported Labels */
#define LABEL_seq_isr 0x268 #define LABEL_seq_isr 0x26d
#define LABEL_timer_isr 0x264 #define LABEL_timer_isr 0x269
...@@ -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#87 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/ */
#include "aic79xx_osm.h" #include "aic79xx_osm.h"
......
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