diff options
author | Salyzyn, Mark <mark_salyzyn@adaptec.com> | 2007-12-13 19:14:18 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:28:07 -0500 |
commit | 94cf6ba11b068b8a8f68a1e88bffb6827e92124b (patch) | |
tree | c5ec05bb60248471ba9992c56dfeb1b44980d24b /drivers/scsi/aacraid/aachba.c | |
parent | 00f5970193e22c48f399a2430635d6416b51befe (diff) |
[SCSI] aacraid: fix driver failure with Dell PowerEdge Expandable RAID Controller 3/Di
As reported in http://bugzilla.kernel.org/show_bug.cgi?id=3D9133 it was
discovered that the PERC line of controllers lacked a key 64 bit
ScatterGather capable SCSI pass-through function. The adapters are still
capable of 64 bit ScatterGather I/O commands, but these two can not be
mixed. This problem was exacerbated by the introduction of the SCSI
Generic access to the DASD physical devices.
The fix for users before this patch is applied is aacraid.dacmode=3D0 on
the kernel command line to disable 64 bit I/O.
The enclosed patch introduces a new adapter quirk and tries to limp
along by enabling pass-through in situations where memory is 32 bit
addressable on 64 bit machines, or disable the pass-through functions
altogether. I expect that the check for 32 bit addressable memory to be
controversial in that it can be incorrect in non-Dell non-Intel systems
that PERC would never be installed under, the alternative is to disable
pass-through in all cases which could be reported as another regression.
Pass-through is used for SCSI Generic access to the physical devices, or
for the management applications to properly function.
In systems where this patch has disabled pass-through because it is
unsupportable in combination with I/O performance, the user can choose
to enable pass-through by turning off dacmode (aacraid.dacmode=3D0) or
limiting the discovered kernel memory (mem=3D4G) with an associated loss
in runtime performance. If we chose instead to turn off 64 bit dacmode
for the adapters with this quirk, then this would be reported as another
regression.
Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 641c303d28ef..cef764eba307 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -1190,6 +1190,15 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd) | |||
1190 | (fib_callback) aac_srb_callback, (void *) cmd); | 1190 | (fib_callback) aac_srb_callback, (void *) cmd); |
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd) | ||
1194 | { | ||
1195 | if ((sizeof(dma_addr_t) > 4) && | ||
1196 | (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) && | ||
1197 | (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) | ||
1198 | return FAILED; | ||
1199 | return aac_scsi_32(fib, cmd); | ||
1200 | } | ||
1201 | |||
1193 | int aac_get_adapter_info(struct aac_dev* dev) | 1202 | int aac_get_adapter_info(struct aac_dev* dev) |
1194 | { | 1203 | { |
1195 | struct fib* fibptr; | 1204 | struct fib* fibptr; |
@@ -1267,6 +1276,8 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1267 | 1, 1, | 1276 | 1, 1, |
1268 | NULL, NULL); | 1277 | NULL, NULL); |
1269 | 1278 | ||
1279 | /* reasoned default */ | ||
1280 | dev->maximum_num_physicals = 16; | ||
1270 | if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) { | 1281 | if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) { |
1271 | dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus); | 1282 | dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus); |
1272 | dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); | 1283 | dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); |
@@ -1377,7 +1388,9 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1377 | * interface. | 1388 | * interface. |
1378 | */ | 1389 | */ |
1379 | dev->a_ops.adapter_scsi = (dev->dac_support) | 1390 | dev->a_ops.adapter_scsi = (dev->dac_support) |
1380 | ? aac_scsi_64 | 1391 | ? ((aac_get_driver_ident(dev->cardtype)->quirks & AAC_QUIRK_SCSI_32) |
1392 | ? aac_scsi_32_64 | ||
1393 | : aac_scsi_64) | ||
1381 | : aac_scsi_32; | 1394 | : aac_scsi_32; |
1382 | if (dev->raw_io_interface) { | 1395 | if (dev->raw_io_interface) { |
1383 | dev->a_ops.adapter_bounds = (dev->raw_io_64) | 1396 | dev->a_ops.adapter_bounds = (dev->raw_io_64) |