diff options
| -rw-r--r-- | drivers/ieee1394/sbp2.c | 49 | ||||
| -rw-r--r-- | drivers/ieee1394/sbp2.h | 1 |
2 files changed, 46 insertions, 4 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index ecd59ef8c8a3..09e9291f1848 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
| @@ -151,6 +151,11 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)" | |||
| 151 | * - skip mode page 8 | 151 | * - skip mode page 8 |
| 152 | * Suppress sending of mode_sense for mode page 8 if the device pretends to | 152 | * Suppress sending of mode_sense for mode page 8 if the device pretends to |
| 153 | * support the SCSI Primary Block commands instead of Reduced Block Commands. | 153 | * support the SCSI Primary Block commands instead of Reduced Block Commands. |
| 154 | * | ||
| 155 | * - fix capacity | ||
| 156 | * Tell sd_mod to correct the last sector number reported by read_capacity. | ||
| 157 | * Avoids access beyond actual disk limits on devices with an off-by-one bug. | ||
| 158 | * Don't use this with devices which don't have this bug. | ||
| 154 | */ | 159 | */ |
| 155 | static int sbp2_default_workarounds; | 160 | static int sbp2_default_workarounds; |
| 156 | module_param_named(workarounds, sbp2_default_workarounds, int, 0644); | 161 | module_param_named(workarounds, sbp2_default_workarounds, int, 0644); |
| @@ -158,6 +163,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" | |||
| 158 | ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS) | 163 | ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS) |
| 159 | ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) | 164 | ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) |
| 160 | ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) | 165 | ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) |
| 166 | ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) | ||
| 161 | ", or a combination)"); | 167 | ", or a combination)"); |
| 162 | 168 | ||
| 163 | /* legacy parameter */ | 169 | /* legacy parameter */ |
| @@ -291,6 +297,7 @@ static struct hpsb_protocol_driver sbp2_driver = { | |||
| 291 | */ | 297 | */ |
| 292 | static const struct { | 298 | static const struct { |
| 293 | u32 firmware_revision; | 299 | u32 firmware_revision; |
| 300 | u32 model_id; | ||
| 294 | unsigned workarounds; | 301 | unsigned workarounds; |
| 295 | } sbp2_workarounds_table[] = { | 302 | } sbp2_workarounds_table[] = { |
| 296 | /* TSB42AA9 */ { | 303 | /* TSB42AA9 */ { |
| @@ -305,6 +312,31 @@ static const struct { | |||
| 305 | /* Symbios bridge */ { | 312 | /* Symbios bridge */ { |
| 306 | .firmware_revision = 0xa0b800, | 313 | .firmware_revision = 0xa0b800, |
| 307 | .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, | 314 | .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, |
| 315 | }, | ||
| 316 | /* | ||
| 317 | * Note about the following Apple iPod blacklist entries: | ||
| 318 | * | ||
| 319 | * There are iPods (2nd gen, 3rd gen) with model_id==0. Since our | ||
| 320 | * matching logic treats 0 as a wildcard, we cannot match this ID | ||
| 321 | * without rewriting the matching routine. Fortunately these iPods | ||
| 322 | * do not feature the read_capacity bug according to one report. | ||
| 323 | * Read_capacity behaviour as well as model_id could change due to | ||
| 324 | * Apple-supplied firmware updates though. | ||
| 325 | */ | ||
| 326 | /* iPod 4th generation */ { | ||
| 327 | .firmware_revision = 0x0a2700, | ||
| 328 | .model_id = 0x000021, | ||
| 329 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | ||
| 330 | }, | ||
| 331 | /* iPod mini */ { | ||
| 332 | .firmware_revision = 0x0a2700, | ||
| 333 | .model_id = 0x000023, | ||
| 334 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | ||
| 335 | }, | ||
| 336 | /* iPod Photo */ { | ||
| 337 | .firmware_revision = 0x0a2700, | ||
| 338 | .model_id = 0x00007e, | ||
| 339 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | ||
| 308 | } | 340 | } |
| 309 | }; | 341 | }; |
| 310 | 342 | ||
| @@ -1556,18 +1588,25 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, | |||
| 1556 | } | 1588 | } |
| 1557 | 1589 | ||
| 1558 | for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) { | 1590 | for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) { |
| 1559 | if (sbp2_workarounds_table[i].firmware_revision != | 1591 | if (sbp2_workarounds_table[i].firmware_revision && |
| 1592 | sbp2_workarounds_table[i].firmware_revision != | ||
| 1560 | (firmware_revision & 0xffff00)) | 1593 | (firmware_revision & 0xffff00)) |
| 1561 | continue; | 1594 | continue; |
| 1595 | if (sbp2_workarounds_table[i].model_id && | ||
| 1596 | sbp2_workarounds_table[i].model_id != ud->model_id) | ||
| 1597 | continue; | ||
| 1562 | workarounds |= sbp2_workarounds_table[i].workarounds; | 1598 | workarounds |= sbp2_workarounds_table[i].workarounds; |
| 1563 | break; | 1599 | break; |
| 1564 | } | 1600 | } |
| 1565 | 1601 | ||
| 1566 | if (workarounds) | 1602 | if (workarounds) |
| 1567 | SBP2_INFO("Workarounds for node " NODE_BUS_FMT ": " | 1603 | SBP2_INFO("Workarounds for node " NODE_BUS_FMT ": 0x%x " |
| 1568 | "0x%x (firmware_revision 0x%x)", | 1604 | "(firmware_revision 0x%06x, vendor_id 0x%06x," |
| 1605 | " model_id 0x%06x)", | ||
| 1569 | NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), | 1606 | NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), |
| 1570 | workarounds, firmware_revision); | 1607 | workarounds, firmware_revision, |
| 1608 | ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id, | ||
| 1609 | ud->model_id); | ||
| 1571 | 1610 | ||
| 1572 | /* We would need one SCSI host template for each target to adjust | 1611 | /* We would need one SCSI host template for each target to adjust |
| 1573 | * max_sectors on the fly, therefore warn only. */ | 1612 | * max_sectors on the fly, therefore warn only. */ |
| @@ -2488,6 +2527,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) | |||
| 2488 | if (sdev->type == TYPE_DISK && | 2527 | if (sdev->type == TYPE_DISK && |
| 2489 | scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8) | 2528 | scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8) |
| 2490 | sdev->skip_ms_page_8 = 1; | 2529 | sdev->skip_ms_page_8 = 1; |
| 2530 | if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) | ||
| 2531 | sdev->fix_capacity = 1; | ||
| 2491 | return 0; | 2532 | return 0; |
| 2492 | } | 2533 | } |
| 2493 | 2534 | ||
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index e40caf5d61ac..3af2710f1858 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
| @@ -238,6 +238,7 @@ struct sbp2_status_block { | |||
| 238 | #define SBP2_WORKAROUND_128K_MAX_TRANS 0x1 | 238 | #define SBP2_WORKAROUND_128K_MAX_TRANS 0x1 |
| 239 | #define SBP2_WORKAROUND_INQUIRY_36 0x2 | 239 | #define SBP2_WORKAROUND_INQUIRY_36 0x2 |
| 240 | #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 | 240 | #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 |
| 241 | #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 | ||
| 241 | 242 | ||
| 242 | /* This is the two dma types we use for cmd_dma below */ | 243 | /* This is the two dma types we use for cmd_dma below */ |
| 243 | enum cmd_dma_types { | 244 | enum cmd_dma_types { |
