[SCSI] sym2: Allow NVRAM settings to limit speed and width
The NVRAM for both Tekram and Symbios boards allows the user to set the speed and width for individual targets. I took that code out in March 2004 when we introduced Domain Validation, but it seems there's still a legitimate need for it in some configurations. Signed-off-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
33333bacf5
commit
b37df48923
5 changed files with 26 additions and 18 deletions
|
@ -1038,6 +1038,9 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
tp->starget = sdev->sdev_target;
|
tp->starget = sdev->sdev_target;
|
||||||
|
spi_min_period(tp->starget) = tp->usr_period;
|
||||||
|
spi_max_width(tp->starget) = tp->usr_width;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -943,7 +943,7 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru
|
||||||
tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
|
tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
|
||||||
tp->usrtags = SYM_SETUP_MAX_TAG;
|
tp->usrtags = SYM_SETUP_MAX_TAG;
|
||||||
|
|
||||||
sym_nvram_setup_target(np, i, nvram);
|
sym_nvram_setup_target(tp, i, nvram);
|
||||||
|
|
||||||
if (!tp->usrtags)
|
if (!tp->usrtags)
|
||||||
tp->usrflags &= ~SYM_TAGS_ENABLED;
|
tp->usrflags &= ~SYM_TAGS_ENABLED;
|
||||||
|
|
|
@ -434,8 +434,10 @@ struct sym_tcb {
|
||||||
* Other user settable limits and options.
|
* Other user settable limits and options.
|
||||||
* These limits are read from the NVRAM if present.
|
* These limits are read from the NVRAM if present.
|
||||||
*/
|
*/
|
||||||
u_char usrflags;
|
unsigned char usrflags;
|
||||||
u_short usrtags;
|
unsigned char usr_period;
|
||||||
|
unsigned char usr_width;
|
||||||
|
unsigned short usrtags;
|
||||||
struct scsi_target *starget;
|
struct scsi_target *starget;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,29 +92,32 @@ void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sy
|
||||||
* Get target set-up from Symbios format NVRAM.
|
* Get target set-up from Symbios format NVRAM.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram)
|
sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram)
|
||||||
{
|
{
|
||||||
struct sym_tcb *tp = &np->target[target];
|
|
||||||
Symbios_target *tn = &nvram->target[target];
|
Symbios_target *tn = &nvram->target[target];
|
||||||
|
|
||||||
tp->usrtags =
|
if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED))
|
||||||
(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0;
|
tp->usrtags = 0;
|
||||||
|
|
||||||
if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
|
if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
|
||||||
tp->usrflags &= ~SYM_DISC_ENABLED;
|
tp->usrflags &= ~SYM_DISC_ENABLED;
|
||||||
if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
|
if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
|
||||||
tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
|
tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
|
||||||
if (!(tn->flags & SYMBIOS_SCAN_LUNS))
|
if (!(tn->flags & SYMBIOS_SCAN_LUNS))
|
||||||
tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
|
tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
|
||||||
|
tp->usr_period = (tn->sync_period + 3) / 4;
|
||||||
|
tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const unsigned char Tekram_sync[16] = {
|
||||||
|
25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get target set-up from Tekram format NVRAM.
|
* Get target set-up from Tekram format NVRAM.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
|
sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram)
|
||||||
{
|
{
|
||||||
struct sym_tcb *tp = &np->target[target];
|
|
||||||
struct Tekram_target *tn = &nvram->target[target];
|
struct Tekram_target *tn = &nvram->target[target];
|
||||||
|
|
||||||
if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
|
if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
|
||||||
|
@ -124,22 +127,22 @@ sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
|
||||||
if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
|
if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
|
||||||
tp->usrflags |= SYM_DISC_ENABLED;
|
tp->usrflags |= SYM_DISC_ENABLED;
|
||||||
|
|
||||||
/* If any device does not support parity, we will not use this option */
|
if (tn->flags & TEKRAM_SYNC_NEGO)
|
||||||
if (!(tn->flags & TEKRAM_PARITY_CHECK))
|
tp->usr_period = Tekram_sync[tn->sync_index & 0xf];
|
||||||
np->rv_scntl0 &= ~0x0a; /* SCSI parity checking disabled */
|
tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get target setup from NVRAM.
|
* Get target setup from NVRAM.
|
||||||
*/
|
*/
|
||||||
void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp)
|
void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp)
|
||||||
{
|
{
|
||||||
switch (nvp->type) {
|
switch (nvp->type) {
|
||||||
case SYM_SYMBIOS_NVRAM:
|
case SYM_SYMBIOS_NVRAM:
|
||||||
sym_Symbios_setup_target(np, target, &nvp->data.Symbios);
|
sym_Symbios_setup_target(tp, target, &nvp->data.Symbios);
|
||||||
break;
|
break;
|
||||||
case SYM_TEKRAM_NVRAM:
|
case SYM_TEKRAM_NVRAM:
|
||||||
sym_Tekram_setup_target(np, target, &nvp->data.Tekram);
|
sym_Tekram_setup_target(tp, target, &nvp->data.Tekram);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -194,12 +194,12 @@ struct sym_nvram {
|
||||||
|
|
||||||
#if SYM_CONF_NVRAM_SUPPORT
|
#if SYM_CONF_NVRAM_SUPPORT
|
||||||
void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
|
void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
|
||||||
void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp);
|
void sym_nvram_setup_target (struct sym_tcb *tp, int target, struct sym_nvram *nvp);
|
||||||
int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
|
int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
|
||||||
char *sym_nvram_type(struct sym_nvram *nvp);
|
char *sym_nvram_type(struct sym_nvram *nvp);
|
||||||
#else
|
#else
|
||||||
static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
|
static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
|
||||||
static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { }
|
static inline void sym_nvram_setup_target(struct sym_tcb *tp, struct sym_nvram *nvram) { }
|
||||||
static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
|
static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
|
||||||
{
|
{
|
||||||
nvp->type = 0;
|
nvp->type = 0;
|
||||||
|
|
Loading…
Reference in a new issue