diff options
| -rw-r--r-- | drivers/ata/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 6 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 29 | ||||
| -rw-r--r-- | drivers/ata/sata_nv.c | 2 | ||||
| -rw-r--r-- | drivers/ata/sata_via.c | 13 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 22 | ||||
| -rw-r--r-- | include/linux/libata.h | 2 | ||||
| -rw-r--r-- | include/scsi/scsi_host.h | 8 |
8 files changed, 80 insertions, 8 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 73f883333a0..aa85a98d3a4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -168,10 +168,10 @@ config ATA_BMDMA | |||
| 168 | default y | 168 | default y |
| 169 | help | 169 | help |
| 170 | This option adds support for SFF ATA controllers with BMDMA | 170 | This option adds support for SFF ATA controllers with BMDMA |
| 171 | capability. BMDMA stands for bus-master DMA and the | 171 | capability. BMDMA stands for bus-master DMA and is the |
| 172 | de-facto DMA interface for SFF controllers. | 172 | de facto DMA interface for SFF controllers. |
| 173 | 173 | ||
| 174 | If unuser, say Y. | 174 | If unsure, say Y. |
| 175 | 175 | ||
| 176 | if ATA_BMDMA | 176 | if ATA_BMDMA |
| 177 | 177 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 06b7e49e039..ddf8e486278 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4119,9 +4119,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
| 4119 | dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) { | 4119 | dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) { |
| 4120 | ata_dev_printk(dev, KERN_WARNING, | 4120 | ata_dev_printk(dev, KERN_WARNING, |
| 4121 | "new n_sectors matches native, probably " | 4121 | "new n_sectors matches native, probably " |
| 4122 | "late HPA unlock, continuing\n"); | 4122 | "late HPA unlock, n_sectors updated\n"); |
| 4123 | /* keep using the old n_sectors */ | 4123 | /* use the larger n_sectors */ |
| 4124 | dev->n_sectors = n_sectors; | ||
| 4125 | return 0; | 4124 | return 0; |
| 4126 | } | 4125 | } |
| 4127 | 4126 | ||
| @@ -6669,6 +6668,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_info); | |||
| 6669 | EXPORT_SYMBOL_GPL(ata_link_next); | 6668 | EXPORT_SYMBOL_GPL(ata_link_next); |
| 6670 | EXPORT_SYMBOL_GPL(ata_dev_next); | 6669 | EXPORT_SYMBOL_GPL(ata_dev_next); |
| 6671 | EXPORT_SYMBOL_GPL(ata_std_bios_param); | 6670 | EXPORT_SYMBOL_GPL(ata_std_bios_param); |
| 6671 | EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity); | ||
| 6672 | EXPORT_SYMBOL_GPL(ata_host_init); | 6672 | EXPORT_SYMBOL_GPL(ata_host_init); |
| 6673 | EXPORT_SYMBOL_GPL(ata_host_alloc); | 6673 | EXPORT_SYMBOL_GPL(ata_host_alloc); |
| 6674 | EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); | 6674 | EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index cfa9dd3d725..a54273d2c3c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -415,6 +415,35 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, | |||
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | /** | 417 | /** |
| 418 | * ata_scsi_unlock_native_capacity - unlock native capacity | ||
| 419 | * @sdev: SCSI device to adjust device capacity for | ||
| 420 | * | ||
| 421 | * This function is called if a partition on @sdev extends beyond | ||
| 422 | * the end of the device. It requests EH to unlock HPA. | ||
| 423 | * | ||
| 424 | * LOCKING: | ||
| 425 | * Defined by the SCSI layer. Might sleep. | ||
| 426 | */ | ||
| 427 | void ata_scsi_unlock_native_capacity(struct scsi_device *sdev) | ||
| 428 | { | ||
| 429 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
| 430 | struct ata_device *dev; | ||
| 431 | unsigned long flags; | ||
| 432 | |||
| 433 | spin_lock_irqsave(ap->lock, flags); | ||
| 434 | |||
| 435 | dev = ata_scsi_find_dev(ap, sdev); | ||
| 436 | if (dev && dev->n_sectors < dev->n_native_sectors) { | ||
| 437 | dev->flags |= ATA_DFLAG_UNLOCK_HPA; | ||
| 438 | dev->link->eh_info.action |= ATA_EH_RESET; | ||
| 439 | ata_port_schedule_eh(ap); | ||
| 440 | } | ||
| 441 | |||
| 442 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 443 | ata_port_wait_eh(ap); | ||
| 444 | } | ||
| 445 | |||
| 446 | /** | ||
| 418 | * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl | 447 | * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl |
| 419 | * @ap: target port | 448 | * @ap: target port |
| 420 | * @sdev: SCSI device to get identify data for | 449 | * @sdev: SCSI device to get identify data for |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 6fd11478411..21161136cad 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
| @@ -1669,7 +1669,6 @@ static void nv_mcp55_freeze(struct ata_port *ap) | |||
| 1669 | mask = readl(mmio_base + NV_INT_ENABLE_MCP55); | 1669 | mask = readl(mmio_base + NV_INT_ENABLE_MCP55); |
| 1670 | mask &= ~(NV_INT_ALL_MCP55 << shift); | 1670 | mask &= ~(NV_INT_ALL_MCP55 << shift); |
| 1671 | writel(mask, mmio_base + NV_INT_ENABLE_MCP55); | 1671 | writel(mask, mmio_base + NV_INT_ENABLE_MCP55); |
| 1672 | ata_sff_freeze(ap); | ||
| 1673 | } | 1672 | } |
| 1674 | 1673 | ||
| 1675 | static void nv_mcp55_thaw(struct ata_port *ap) | 1674 | static void nv_mcp55_thaw(struct ata_port *ap) |
| @@ -1683,7 +1682,6 @@ static void nv_mcp55_thaw(struct ata_port *ap) | |||
| 1683 | mask = readl(mmio_base + NV_INT_ENABLE_MCP55); | 1682 | mask = readl(mmio_base + NV_INT_ENABLE_MCP55); |
| 1684 | mask |= (NV_INT_MASK_MCP55 << shift); | 1683 | mask |= (NV_INT_MASK_MCP55 << shift); |
| 1685 | writel(mask, mmio_base + NV_INT_ENABLE_MCP55); | 1684 | writel(mask, mmio_base + NV_INT_ENABLE_MCP55); |
| 1686 | ata_sff_thaw(ap); | ||
| 1687 | } | 1685 | } |
| 1688 | 1686 | ||
| 1689 | static void nv_adma_error_handler(struct ata_port *ap) | 1687 | static void nv_adma_error_handler(struct ata_port *ap) |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 101d8c219ca..0ecd0f6aa2c 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
| @@ -575,6 +575,19 @@ static void svia_configure(struct pci_dev *pdev) | |||
| 575 | tmp8 |= NATIVE_MODE_ALL; | 575 | tmp8 |= NATIVE_MODE_ALL; |
| 576 | pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); | 576 | pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); |
| 577 | } | 577 | } |
| 578 | |||
| 579 | /* | ||
| 580 | * vt6421 has problems talking to some drives. The following | ||
| 581 | * is the magic fix from Joseph Chan <JosephChan@via.com.tw>. | ||
| 582 | * Please add proper documentation if possible. | ||
| 583 | * | ||
| 584 | * https://bugzilla.kernel.org/show_bug.cgi?id=15173 | ||
| 585 | */ | ||
| 586 | if (pdev->device == 0x3249) { | ||
| 587 | pci_read_config_byte(pdev, 0x52, &tmp8); | ||
| 588 | tmp8 |= 1 << 2; | ||
| 589 | pci_write_config_byte(pdev, 0x52, tmp8); | ||
| 590 | } | ||
| 578 | } | 591 | } |
| 579 | 592 | ||
| 580 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 593 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 829cc37abc4..8802e48bc06 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -97,6 +97,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | |||
| 97 | #endif | 97 | #endif |
| 98 | 98 | ||
| 99 | static int sd_revalidate_disk(struct gendisk *); | 99 | static int sd_revalidate_disk(struct gendisk *); |
| 100 | static void sd_unlock_native_capacity(struct gendisk *disk); | ||
| 100 | static int sd_probe(struct device *); | 101 | static int sd_probe(struct device *); |
| 101 | static int sd_remove(struct device *); | 102 | static int sd_remove(struct device *); |
| 102 | static void sd_shutdown(struct device *); | 103 | static void sd_shutdown(struct device *); |
| @@ -1101,6 +1102,7 @@ static const struct block_device_operations sd_fops = { | |||
| 1101 | #endif | 1102 | #endif |
| 1102 | .media_changed = sd_media_changed, | 1103 | .media_changed = sd_media_changed, |
| 1103 | .revalidate_disk = sd_revalidate_disk, | 1104 | .revalidate_disk = sd_revalidate_disk, |
| 1105 | .unlock_native_capacity = sd_unlock_native_capacity, | ||
| 1104 | }; | 1106 | }; |
| 1105 | 1107 | ||
| 1106 | static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) | 1108 | static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) |
| @@ -2121,6 +2123,26 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 2121 | } | 2123 | } |
| 2122 | 2124 | ||
| 2123 | /** | 2125 | /** |
| 2126 | * sd_unlock_native_capacity - unlock native capacity | ||
| 2127 | * @disk: struct gendisk to set capacity for | ||
| 2128 | * | ||
| 2129 | * Block layer calls this function if it detects that partitions | ||
| 2130 | * on @disk reach beyond the end of the device. If the SCSI host | ||
| 2131 | * implements ->unlock_native_capacity() method, it's invoked to | ||
| 2132 | * give it a chance to adjust the device capacity. | ||
| 2133 | * | ||
| 2134 | * CONTEXT: | ||
| 2135 | * Defined by block layer. Might sleep. | ||
| 2136 | */ | ||
| 2137 | static void sd_unlock_native_capacity(struct gendisk *disk) | ||
| 2138 | { | ||
| 2139 | struct scsi_device *sdev = scsi_disk(disk)->device; | ||
| 2140 | |||
| 2141 | if (sdev->host->hostt->unlock_native_capacity) | ||
| 2142 | sdev->host->hostt->unlock_native_capacity(sdev); | ||
| 2143 | } | ||
| 2144 | |||
| 2145 | /** | ||
| 2124 | * sd_format_disk_name - format disk name | 2146 | * sd_format_disk_name - format disk name |
| 2125 | * @prefix: name prefix - ie. "sd" for SCSI disks | 2147 | * @prefix: name prefix - ie. "sd" for SCSI disks |
| 2126 | * @index: index of the disk to format name for | 2148 | * @index: index of the disk to format name for |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 3bad2701bfa..b85f3ff34d7 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -1023,6 +1023,7 @@ extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
| 1023 | extern int ata_std_bios_param(struct scsi_device *sdev, | 1023 | extern int ata_std_bios_param(struct scsi_device *sdev, |
| 1024 | struct block_device *bdev, | 1024 | struct block_device *bdev, |
| 1025 | sector_t capacity, int geom[]); | 1025 | sector_t capacity, int geom[]); |
| 1026 | extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); | ||
| 1026 | extern int ata_scsi_slave_config(struct scsi_device *sdev); | 1027 | extern int ata_scsi_slave_config(struct scsi_device *sdev); |
| 1027 | extern void ata_scsi_slave_destroy(struct scsi_device *sdev); | 1028 | extern void ata_scsi_slave_destroy(struct scsi_device *sdev); |
| 1028 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, | 1029 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, |
| @@ -1174,6 +1175,7 @@ extern struct device_attribute *ata_common_sdev_attrs[]; | |||
| 1174 | .slave_configure = ata_scsi_slave_config, \ | 1175 | .slave_configure = ata_scsi_slave_config, \ |
| 1175 | .slave_destroy = ata_scsi_slave_destroy, \ | 1176 | .slave_destroy = ata_scsi_slave_destroy, \ |
| 1176 | .bios_param = ata_std_bios_param, \ | 1177 | .bios_param = ata_std_bios_param, \ |
| 1178 | .unlock_native_capacity = ata_scsi_unlock_native_capacity, \ | ||
| 1177 | .sdev_attrs = ata_common_sdev_attrs | 1179 | .sdev_attrs = ata_common_sdev_attrs |
| 1178 | 1180 | ||
| 1179 | #define ATA_NCQ_SHT(drv_name) \ | 1181 | #define ATA_NCQ_SHT(drv_name) \ |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index c50a97fc76f..b7bdecb7b76 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
| @@ -327,6 +327,14 @@ struct scsi_host_template { | |||
| 327 | sector_t, int []); | 327 | sector_t, int []); |
| 328 | 328 | ||
| 329 | /* | 329 | /* |
| 330 | * This function is called when one or more partitions on the | ||
| 331 | * device reach beyond the end of the device. | ||
| 332 | * | ||
| 333 | * Status: OPTIONAL | ||
| 334 | */ | ||
| 335 | void (*unlock_native_capacity)(struct scsi_device *); | ||
| 336 | |||
| 337 | /* | ||
| 330 | * Can be used to export driver statistics and other infos to the | 338 | * Can be used to export driver statistics and other infos to the |
| 331 | * world outside the kernel ie. userspace and it also provides an | 339 | * world outside the kernel ie. userspace and it also provides an |
| 332 | * interface to feed the driver with information. | 340 | * interface to feed the driver with information. |
