diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b70247110608..97feb50675cf 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -4072,6 +4072,30 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) | |||
4072 | return 0; | 4072 | return 0; |
4073 | } | 4073 | } |
4074 | 4074 | ||
4075 | /* Interrogate the hardware for some limits: | ||
4076 | * max commands, max SG elements without chaining, and with chaining, | ||
4077 | * SG chain block size, etc. | ||
4078 | */ | ||
4079 | static void __devinit cciss_find_board_params(ctlr_info_t *h) | ||
4080 | { | ||
4081 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | ||
4082 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ | ||
4083 | h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); | ||
4084 | /* | ||
4085 | * Limit in-command s/g elements to 32 save dma'able memory. | ||
4086 | * Howvever spec says if 0, use 31 | ||
4087 | */ | ||
4088 | h->max_cmd_sgentries = 31; | ||
4089 | if (h->maxsgentries > 512) { | ||
4090 | h->max_cmd_sgentries = 32; | ||
4091 | h->chainsize = h->maxsgentries - h->max_cmd_sgentries + 1; | ||
4092 | h->maxsgentries--; /* save one for chain pointer */ | ||
4093 | } else { | ||
4094 | h->maxsgentries = 31; /* default to traditional values */ | ||
4095 | h->chainsize = 0; | ||
4096 | } | ||
4097 | } | ||
4098 | |||
4075 | static int __devinit cciss_pci_init(ctlr_info_t *c) | 4099 | static int __devinit cciss_pci_init(ctlr_info_t *c) |
4076 | { | 4100 | { |
4077 | int prod_index, err; | 4101 | int prod_index, err; |
@@ -4127,34 +4151,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) | |||
4127 | #ifdef CCISS_DEBUG | 4151 | #ifdef CCISS_DEBUG |
4128 | print_cfg_table(c->cfgtable); | 4152 | print_cfg_table(c->cfgtable); |
4129 | #endif /* CCISS_DEBUG */ | 4153 | #endif /* CCISS_DEBUG */ |
4154 | cciss_find_board_params(c); | ||
4130 | 4155 | ||
4131 | /* Some controllers support Zero Memory Raid (ZMR). | ||
4132 | * When configured in ZMR mode the number of supported | ||
4133 | * commands drops to 64. So instead of just setting an | ||
4134 | * arbitrary value we make the driver a little smarter. | ||
4135 | * We read the config table to tell us how many commands | ||
4136 | * are supported on the controller then subtract 4 to | ||
4137 | * leave a little room for ioctl calls. | ||
4138 | */ | ||
4139 | c->max_commands = readl(&(c->cfgtable->MaxPerformantModeCommands)); | ||
4140 | c->maxsgentries = readl(&(c->cfgtable->MaxSGElements)); | ||
4141 | |||
4142 | /* | ||
4143 | * Limit native command to 32 s/g elements to save dma'able memory. | ||
4144 | * Howvever spec says if 0, use 31 | ||
4145 | */ | ||
4146 | |||
4147 | c->max_cmd_sgentries = 31; | ||
4148 | if (c->maxsgentries > 512) { | ||
4149 | c->max_cmd_sgentries = 32; | ||
4150 | c->chainsize = c->maxsgentries - c->max_cmd_sgentries + 1; | ||
4151 | c->maxsgentries -= 1; /* account for chain pointer */ | ||
4152 | } else { | ||
4153 | c->maxsgentries = 31; /* Default to traditional value */ | ||
4154 | c->chainsize = 0; /* traditional */ | ||
4155 | } | ||
4156 | |||
4157 | c->nr_cmds = c->max_commands - 4; | ||
4158 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || | 4156 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || |
4159 | (readb(&c->cfgtable->Signature[1]) != 'I') || | 4157 | (readb(&c->cfgtable->Signature[1]) != 'I') || |
4160 | (readb(&c->cfgtable->Signature[2]) != 'S') || | 4158 | (readb(&c->cfgtable->Signature[2]) != 'S') || |