aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2006-01-24 04:44:38 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-31 15:39:48 -0500
commit3fb086126462c2de06dddaec58981d8827be100d (patch)
treeeaa3e79ef84f8a68246e0ba68a1d048b03e9acd4 /drivers/scsi
parent53467e636b7beb350c307cc88323aae4676577f2 (diff)
[SCSI] aic79xx: SLOWCRC fix
This patch introduces the SLOWCRC handling for certain buggy chipsets. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.h3
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c21
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c17
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c11
4 files changed, 49 insertions, 3 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
index 2cfdbef447db..1d11f7e77564 100644
--- a/drivers/scsi/aic7xxx/aic79xx.h
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -37,7 +37,7 @@
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES. 38 * POSSIBILITY OF SUCH DAMAGES.
39 * 39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $ 40 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#109 $
41 * 41 *
42 * $FreeBSD$ 42 * $FreeBSD$
43 */ 43 */
@@ -222,6 +222,7 @@ typedef enum {
222typedef enum { 222typedef enum {
223 AHD_FENONE = 0x00000, 223 AHD_FENONE = 0x00000,
224 AHD_WIDE = 0x00001,/* Wide Channel */ 224 AHD_WIDE = 0x00001,/* Wide Channel */
225 AHD_AIC79XXB_SLOWCRC = 0x00002,/* SLOWCRC bit should be set */
225 AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */ 226 AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */
226 AHD_TARGETMODE = 0x01000,/* Has tested target mode support */ 227 AHD_TARGETMODE = 0x01000,/* Has tested target mode support */
227 AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */ 228 AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index dfd4cc93c05c..6114b3e72caa 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -3332,6 +3332,15 @@ ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3332 con_opts |= WIDEXFER; 3332 con_opts |= WIDEXFER;
3333 3333
3334 /* 3334 /*
3335 * Slow down our CRC interval to be
3336 * compatible with packetized U320 devices
3337 * that can't handle a CRC at full speed
3338 */
3339 if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
3340 con_opts |= ENSLOWCRC;
3341 }
3342
3343 /*
3335 * During packetized transfers, the target will 3344 * During packetized transfers, the target will
3336 * give us the oportunity to send command packets 3345 * give us the oportunity to send command packets
3337 * without us asserting attention. 3346 * without us asserting attention.
@@ -6740,6 +6749,18 @@ ahd_chip_init(struct ahd_softc *ahd)
6740 6749
6741 ahd_loadseq(ahd); 6750 ahd_loadseq(ahd);
6742 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); 6751 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6752
6753 if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
6754 u_int negodat3 = ahd_inb(ahd, NEGCONOPTS);
6755
6756 negodat3 |= ENSLOWCRC;
6757 ahd_outb(ahd, NEGCONOPTS, negodat3);
6758 negodat3 = ahd_inb(ahd, NEGCONOPTS);
6759 if (!(negodat3 & ENSLOWCRC))
6760 printf("aic79xx: failed to set the SLOWCRC bit\n");
6761 else
6762 printf("aic79xx: SLOWCRC bit set\n");
6763 }
6743} 6764}
6744 6765
6745/* 6766/*
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 2567e29960bd..815c06312c88 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -314,6 +314,21 @@ static uint32_t aic79xx_seltime;
314 */ 314 */
315uint32_t aic79xx_periodic_otag; 315uint32_t aic79xx_periodic_otag;
316 316
317/* Some storage boxes are using an LSI chip which has a bug making it
318 * impossible to use aic79xx Rev B chip in 320 speeds. The following
319 * storage boxes have been reported to be buggy:
320 * EonStor 3U 16-Bay: U16U-G3A3
321 * EonStor 2U 12-Bay: U12U-G3A3
322 * SentinelRAID: 2500F R5 / R6
323 * SentinelRAID: 2500F R1
324 * SentinelRAID: 2500F/1500F
325 * SentinelRAID: 150F
326 *
327 * To get around this LSI bug, you can set your board to 160 mode
328 * or you can enable the SLOWCRC bit.
329 */
330uint32_t aic79xx_slowcrc;
331
317/* 332/*
318 * Module information and settable options. 333 * Module information and settable options.
319 */ 334 */
@@ -343,6 +358,7 @@ MODULE_PARM_DESC(aic79xx,
343" amplitude:<int> Set the signal amplitude (0-7).\n" 358" amplitude:<int> Set the signal amplitude (0-7).\n"
344" seltime:<int> Selection Timeout:\n" 359" seltime:<int> Selection Timeout:\n"
345" (0/256ms,1/128ms,2/64ms,3/32ms)\n" 360" (0/256ms,1/128ms,2/64ms,3/32ms)\n"
361" slowcrc Turn on the SLOWCRC bit (Rev B only)\n"
346"\n" 362"\n"
347" Sample /etc/modprobe.conf line:\n" 363" Sample /etc/modprobe.conf line:\n"
348" Enable verbose logging\n" 364" Enable verbose logging\n"
@@ -1003,6 +1019,7 @@ aic79xx_setup(char *s)
1003 { "slewrate", NULL }, 1019 { "slewrate", NULL },
1004 { "precomp", NULL }, 1020 { "precomp", NULL },
1005 { "amplitude", NULL }, 1021 { "amplitude", NULL },
1022 { "slowcrc", &aic79xx_slowcrc },
1006 }; 1023 };
1007 1024
1008 end = strchr(s, '\0'); 1025 end = strchr(s, '\0');
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index 196a6344b037..757242e522c2 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -38,7 +38,7 @@
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES. 39 * POSSIBILITY OF SUCH DAMAGES.
40 * 40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#89 $ 41 * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#92 $
42 */ 42 */
43 43
44#ifdef __linux__ 44#ifdef __linux__
@@ -950,12 +950,19 @@ ahd_aic790X_setup(struct ahd_softc *ahd)
950 if ((ahd->flags & AHD_HP_BOARD) == 0) 950 if ((ahd->flags & AHD_HP_BOARD) == 0)
951 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA); 951 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
952 } else { 952 } else {
953 /* This is revision B and newer. */
954 extern uint32_t aic79xx_slowcrc;
953 u_int devconfig1; 955 u_int devconfig1;
954 956
955 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS 957 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
956 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY; 958 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY
959 | AHD_BUSFREEREV_BUG;
957 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG; 960 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
958 961
962 /* If the user requested the the SLOWCRC bit to be set. */
963 if (aic79xx_slowcrc)
964 ahd->features |= AHD_AIC79XXB_SLOWCRC;
965
959 /* 966 /*
960 * Some issues have been resolved in the 7901B. 967 * Some issues have been resolved in the 7901B.
961 */ 968 */