Commit 6250d3af authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz

Merge branch 'for-linus' into for-next

parents 4c9773ed 075affcb
...@@ -216,6 +216,8 @@ Other kernel parameters for ide_core are: ...@@ -216,6 +216,8 @@ Other kernel parameters for ide_core are:
* "noflush=[interface_number.device_number]" to disable flush requests * "noflush=[interface_number.device_number]" to disable flush requests
* "nohpa=[interface_number.device_number]" to disable Host Protected Area
* "noprobe=[interface_number.device_number]" to skip probing * "noprobe=[interface_number.device_number]" to skip probing
* "nowerr=[interface_number.device_number]" to ignore the WRERR_STAT bit * "nowerr=[interface_number.device_number]" to ignore the WRERR_STAT bit
......
...@@ -835,11 +835,8 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -835,11 +835,8 @@ and is between 256 and 4096 characters. It is defined in the file
ide-core.nodma= [HW] (E)IDE subsystem ide-core.nodma= [HW] (E)IDE subsystem
Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
.vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom .vlb_clock .pci_clock .noflush .nohpa .noprobe .nowerr
.chs .ignore_cable are additional options .cdrom .chs .ignore_cable are additional options
See Documentation/ide/ide.txt.
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
See Documentation/ide/ide.txt. See Documentation/ide/ide.txt.
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
......
...@@ -302,13 +302,11 @@ static const struct drive_list_entry hpa_list[] = { ...@@ -302,13 +302,11 @@ static const struct drive_list_entry hpa_list[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static void idedisk_check_hpa(ide_drive_t *drive) static u64 ide_disk_hpa_get_native_capacity(ide_drive_t *drive, int lba48)
{ {
unsigned long long capacity, set_max; u64 capacity, set_max;
int lba48 = ata_id_lba48_enabled(drive->id);
capacity = drive->capacity64; capacity = drive->capacity64;
set_max = idedisk_read_native_max_address(drive, lba48); set_max = idedisk_read_native_max_address(drive, lba48);
if (ide_in_drive_list(drive->id, hpa_list)) { if (ide_in_drive_list(drive->id, hpa_list)) {
...@@ -320,9 +318,31 @@ static void idedisk_check_hpa(ide_drive_t *drive) ...@@ -320,9 +318,31 @@ static void idedisk_check_hpa(ide_drive_t *drive)
set_max--; set_max--;
} }
return set_max;
}
static u64 ide_disk_hpa_set_capacity(ide_drive_t *drive, u64 set_max, int lba48)
{
set_max = idedisk_set_max_address(drive, set_max, lba48);
if (set_max)
drive->capacity64 = set_max;
return set_max;
}
static void idedisk_check_hpa(ide_drive_t *drive)
{
u64 capacity, set_max;
int lba48 = ata_id_lba48_enabled(drive->id);
capacity = drive->capacity64;
set_max = ide_disk_hpa_get_native_capacity(drive, lba48);
if (set_max <= capacity) if (set_max <= capacity)
return; return;
drive->probed_capacity = set_max;
printk(KERN_INFO "%s: Host Protected Area detected.\n" printk(KERN_INFO "%s: Host Protected Area detected.\n"
"\tcurrent capacity is %llu sectors (%llu MB)\n" "\tcurrent capacity is %llu sectors (%llu MB)\n"
"\tnative capacity is %llu sectors (%llu MB)\n", "\tnative capacity is %llu sectors (%llu MB)\n",
...@@ -330,13 +350,13 @@ static void idedisk_check_hpa(ide_drive_t *drive) ...@@ -330,13 +350,13 @@ static void idedisk_check_hpa(ide_drive_t *drive)
capacity, sectors_to_MB(capacity), capacity, sectors_to_MB(capacity),
set_max, sectors_to_MB(set_max)); set_max, sectors_to_MB(set_max));
set_max = idedisk_set_max_address(drive, set_max, lba48); if ((drive->dev_flags & IDE_DFLAG_NOHPA) == 0)
return;
if (set_max) { set_max = ide_disk_hpa_set_capacity(drive, set_max, lba48);
drive->capacity64 = set_max; if (set_max)
printk(KERN_INFO "%s: Host Protected Area disabled.\n", printk(KERN_INFO "%s: Host Protected Area disabled.\n",
drive->name); drive->name);
}
} }
static int ide_disk_get_capacity(ide_drive_t *drive) static int ide_disk_get_capacity(ide_drive_t *drive)
...@@ -358,6 +378,8 @@ static int ide_disk_get_capacity(ide_drive_t *drive) ...@@ -358,6 +378,8 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
drive->capacity64 = drive->cyl * drive->head * drive->sect; drive->capacity64 = drive->cyl * drive->head * drive->sect;
} }
drive->probed_capacity = drive->capacity64;
if (lba) { if (lba) {
drive->dev_flags |= IDE_DFLAG_LBA; drive->dev_flags |= IDE_DFLAG_LBA;
...@@ -376,7 +398,7 @@ static int ide_disk_get_capacity(ide_drive_t *drive) ...@@ -376,7 +398,7 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
"%llu sectors (%llu MB)\n", "%llu sectors (%llu MB)\n",
drive->name, (unsigned long long)drive->capacity64, drive->name, (unsigned long long)drive->capacity64,
sectors_to_MB(drive->capacity64)); sectors_to_MB(drive->capacity64));
drive->capacity64 = 1ULL << 28; drive->probed_capacity = drive->capacity64 = 1ULL << 28;
} }
if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
...@@ -392,6 +414,34 @@ static int ide_disk_get_capacity(ide_drive_t *drive) ...@@ -392,6 +414,34 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
return 0; return 0;
} }
static u64 ide_disk_set_capacity(ide_drive_t *drive, u64 capacity)
{
u64 set = min(capacity, drive->probed_capacity);
u16 *id = drive->id;
int lba48 = ata_id_lba48_enabled(id);
if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 ||
ata_id_hpa_enabled(id) == 0)
goto out;
/*
* according to the spec the SET MAX ADDRESS command shall be
* immediately preceded by a READ NATIVE MAX ADDRESS command
*/
capacity = ide_disk_hpa_get_native_capacity(drive, lba48);
if (capacity == 0)
goto out;
set = ide_disk_hpa_set_capacity(drive, set, lba48);
if (set) {
/* needed for ->resume to disable HPA */
drive->dev_flags |= IDE_DFLAG_NOHPA;
return set;
}
out:
return drive->capacity64;
}
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
{ {
ide_drive_t *drive = q->queuedata; ide_drive_t *drive = q->queuedata;
...@@ -740,6 +790,7 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, ...@@ -740,6 +790,7 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
const struct ide_disk_ops ide_ata_disk_ops = { const struct ide_disk_ops ide_ata_disk_ops = {
.check = ide_disk_check, .check = ide_disk_check,
.set_capacity = ide_disk_set_capacity,
.get_capacity = ide_disk_get_capacity, .get_capacity = ide_disk_get_capacity,
.setup = ide_disk_setup, .setup = ide_disk_setup,
.flush = ide_disk_flush, .flush = ide_disk_flush,
......
...@@ -287,6 +287,19 @@ static int ide_gd_media_changed(struct gendisk *disk) ...@@ -287,6 +287,19 @@ static int ide_gd_media_changed(struct gendisk *disk)
return ret; return ret;
} }
static unsigned long long ide_gd_set_capacity(struct gendisk *disk,
unsigned long long capacity)
{
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
const struct ide_disk_ops *disk_ops = drive->disk_ops;
if (disk_ops->set_capacity)
return disk_ops->set_capacity(drive, capacity);
return drive->capacity64;
}
static int ide_gd_revalidate_disk(struct gendisk *disk) static int ide_gd_revalidate_disk(struct gendisk *disk)
{ {
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
...@@ -315,6 +328,7 @@ static struct block_device_operations ide_gd_ops = { ...@@ -315,6 +328,7 @@ static struct block_device_operations ide_gd_ops = {
.locked_ioctl = ide_gd_ioctl, .locked_ioctl = ide_gd_ioctl,
.getgeo = ide_gd_getgeo, .getgeo = ide_gd_getgeo,
.media_changed = ide_gd_media_changed, .media_changed = ide_gd_media_changed,
.set_capacity = ide_gd_set_capacity,
.revalidate_disk = ide_gd_revalidate_disk .revalidate_disk = ide_gd_revalidate_disk
}; };
......
...@@ -33,6 +33,16 @@ static int ide_generic_all; /* Set to claim all devices */ ...@@ -33,6 +33,16 @@ static int ide_generic_all; /* Set to claim all devices */
module_param_named(all_generic_ide, ide_generic_all, bool, 0444); module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
static void netcell_quirkproc(ide_drive_t *drive)
{
/* mark words 85-87 as valid */
drive->id[ATA_ID_CSF_DEFAULT] |= 0x4000;
}
static const struct ide_port_ops netcell_port_ops = {
.quirkproc = netcell_quirkproc,
};
#define DECLARE_GENERIC_PCI_DEV(extra_flags) \ #define DECLARE_GENERIC_PCI_DEV(extra_flags) \
{ \ { \
.name = DRV_NAME, \ .name = DRV_NAME, \
...@@ -74,6 +84,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { ...@@ -74,6 +84,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
{ /* 6: Revolution */ { /* 6: Revolution */
.name = DRV_NAME, .name = DRV_NAME,
.port_ops = &netcell_port_ops,
.host_flags = IDE_HFLAG_CLEAR_SIMPLEX | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
IDE_HFLAG_TRUST_BIOS_FOR_DMA | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD, IDE_HFLAG_OFF_BOARD,
......
...@@ -211,6 +211,11 @@ static unsigned int ide_noflush; ...@@ -211,6 +211,11 @@ static unsigned int ide_noflush;
module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0); module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0);
MODULE_PARM_DESC(noflush, "disable flush requests for a device"); MODULE_PARM_DESC(noflush, "disable flush requests for a device");
static unsigned int ide_nohpa;
module_param_call(nohpa, ide_set_dev_param_mask, NULL, &ide_nohpa, 0);
MODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device");
static unsigned int ide_noprobe; static unsigned int ide_noprobe;
module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0); module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0);
...@@ -281,6 +286,11 @@ static void ide_dev_apply_params(ide_drive_t *drive, u8 unit) ...@@ -281,6 +286,11 @@ static void ide_dev_apply_params(ide_drive_t *drive, u8 unit)
drive->name); drive->name);
drive->dev_flags |= IDE_DFLAG_NOFLUSH; drive->dev_flags |= IDE_DFLAG_NOFLUSH;
} }
if (ide_nohpa & (1 << i)) {
printk(KERN_INFO "ide: disabling Host Protected Area for %s\n",
drive->name);
drive->dev_flags |= IDE_DFLAG_NOHPA;
}
if (ide_noprobe & (1 << i)) { if (ide_noprobe & (1 << i)) {
printk(KERN_INFO "ide: skipping probe for %s\n", drive->name); printk(KERN_INFO "ide: skipping probe for %s\n", drive->name);
drive->dev_flags |= IDE_DFLAG_NOPROBE; drive->dev_flags |= IDE_DFLAG_NOPROBE;
......
/* /*
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc. * Copyright (C) 2006-2007, 2009 MontaVista Software, Inc.
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
* *
* Portions Copyright (C) 1999 Promise Technology, Inc. * Portions Copyright (C) 1999 Promise Technology, Inc.
...@@ -227,28 +227,19 @@ static int pdc202xx_dma_test_irq(ide_drive_t *drive) ...@@ -227,28 +227,19 @@ static int pdc202xx_dma_test_irq(ide_drive_t *drive)
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
} }
static void pdc202xx_reset_host (ide_hwif_t *hwif) static void pdc202xx_reset(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = drive->hwif;
unsigned long high_16 = hwif->extra_base - 16; unsigned long high_16 = hwif->extra_base - 16;
u8 udma_speed_flag = inb(high_16 | 0x001f); u8 udma_speed_flag = inb(high_16 | 0x001f);
printk(KERN_WARNING "PDC202xx: software reset...\n");
outb(udma_speed_flag | 0x10, high_16 | 0x001f); outb(udma_speed_flag | 0x10, high_16 | 0x001f);
mdelay(100); mdelay(100);
outb(udma_speed_flag & ~0x10, high_16 | 0x001f); outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
mdelay(2000); /* 2 seconds ?! */ mdelay(2000); /* 2 seconds ?! */
printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
hwif->channel ? "Secondary" : "Primary");
}
static void pdc202xx_reset (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
ide_hwif_t *mate = hwif->mate;
pdc202xx_reset_host(hwif);
pdc202xx_reset_host(mate);
ide_set_max_pio(drive); ide_set_max_pio(drive);
} }
...@@ -328,9 +319,8 @@ static const struct ide_dma_ops pdc20246_dma_ops = { ...@@ -328,9 +319,8 @@ static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_start = ide_dma_start, .dma_start = ide_dma_start,
.dma_end = ide_dma_end, .dma_end = ide_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq, .dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq, .dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status, .dma_sff_read_status = ide_dma_sff_read_status,
}; };
......
...@@ -546,28 +546,50 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) ...@@ -546,28 +546,50 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
/* add partitions */ /* add partitions */
for (p = 1; p < state->limit; p++) { for (p = 1; p < state->limit; p++) {
sector_t size = state->parts[p].size; sector_t size, from;
sector_t from = state->parts[p].from; try_scan:
size = state->parts[p].size;
if (!size) if (!size)
continue; continue;
from = state->parts[p].from;
if (from >= get_capacity(disk)) { if (from >= get_capacity(disk)) {
printk(KERN_WARNING printk(KERN_WARNING
"%s: p%d ignored, start %llu is behind the end of the disk\n", "%s: p%d ignored, start %llu is behind the end of the disk\n",
disk->disk_name, p, (unsigned long long) from); disk->disk_name, p, (unsigned long long) from);
continue; continue;
} }
if (from + size > get_capacity(disk)) { if (from + size > get_capacity(disk)) {
struct block_device_operations *bdops = disk->fops;
unsigned long long capacity;
printk(KERN_WARNING
"%s: p%d size %llu exceeds device capacity, ",
disk->disk_name, p, (unsigned long long) size);
if (bdops->set_capacity &&
(disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) {
printk(KERN_CONT "enabling native capacity\n");
capacity = bdops->set_capacity(disk, ~0ULL);
disk->flags |= GENHD_FL_NATIVE_CAPACITY;
if (capacity > get_capacity(disk)) {
set_capacity(disk, capacity);
check_disk_size_change(disk, bdev);
bdev->bd_invalidated = 0;
}
goto try_scan;
} else {
/* /*
* we can not ignore partitions of broken tables * we can not ignore partitions of broken tables
* created by for example camera firmware, but we * created by for example camera firmware, but
* limit them to the end of the disk to avoid * we limit them to the end of the disk to avoid
* creating invalid block devices * creating invalid block devices
*/ */
printk(KERN_WARNING printk(KERN_CONT "limited to end of disk\n");
"%s: p%d size %llu limited to end of disk\n",
disk->disk_name, p, (unsigned long long) size);
size = get_capacity(disk) - from; size = get_capacity(disk) - from;
} }
}
part = add_partition(disk, p, from, size, part = add_partition(disk, p, from, size,
state->parts[p].flags); state->parts[p].flags);
if (IS_ERR(part)) { if (IS_ERR(part)) {
......
...@@ -1106,6 +1106,8 @@ struct block_device_operations { ...@@ -1106,6 +1106,8 @@ struct block_device_operations {
int (*direct_access) (struct block_device *, sector_t, int (*direct_access) (struct block_device *, sector_t,
void **, unsigned long *); void **, unsigned long *);
int (*media_changed) (struct gendisk *); int (*media_changed) (struct gendisk *);
unsigned long long (*set_capacity) (struct gendisk *,
unsigned long long);
int (*revalidate_disk) (struct gendisk *); int (*revalidate_disk) (struct gendisk *);
int (*getgeo)(struct block_device *, struct hd_geometry *); int (*getgeo)(struct block_device *, struct hd_geometry *);
struct module *owner; struct module *owner;
......
...@@ -113,6 +113,7 @@ struct hd_struct { ...@@ -113,6 +113,7 @@ struct hd_struct {
#define GENHD_FL_UP 16 #define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32
#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */
#define GENHD_FL_NATIVE_CAPACITY 128
#define BLK_SCSI_MAX_CMDS (256) #define BLK_SCSI_MAX_CMDS (256)
#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
......
...@@ -381,6 +381,7 @@ struct ide_drive_s; ...@@ -381,6 +381,7 @@ struct ide_drive_s;
struct ide_disk_ops { struct ide_disk_ops {
int (*check)(struct ide_drive_s *, const char *); int (*check)(struct ide_drive_s *, const char *);
int (*get_capacity)(struct ide_drive_s *); int (*get_capacity)(struct ide_drive_s *);
u64 (*set_capacity)(struct ide_drive_s *, u64);
void (*setup)(struct ide_drive_s *); void (*setup)(struct ide_drive_s *);
void (*flush)(struct ide_drive_s *); void (*flush)(struct ide_drive_s *);
int (*init_media)(struct ide_drive_s *, struct gendisk *); int (*init_media)(struct ide_drive_s *, struct gendisk *);
...@@ -458,6 +459,8 @@ enum { ...@@ -458,6 +459,8 @@ enum {
IDE_DFLAG_NICE1 = (1 << 5), IDE_DFLAG_NICE1 = (1 << 5),
/* device is physically present */ /* device is physically present */
IDE_DFLAG_PRESENT = (1 << 6), IDE_DFLAG_PRESENT = (1 << 6),
/* disable Host Protected Area */
IDE_DFLAG_NOHPA = (1 << 7),
/* id read from device (synthetic if not set) */ /* id read from device (synthetic if not set) */
IDE_DFLAG_ID_READ = (1 << 8), IDE_DFLAG_ID_READ = (1 << 8),
IDE_DFLAG_NOPROBE = (1 << 9), IDE_DFLAG_NOPROBE = (1 << 9),
...@@ -552,8 +555,7 @@ struct ide_drive_s { ...@@ -552,8 +555,7 @@ struct ide_drive_s {
unsigned int drive_data; /* used by set_pio_mode/dev_select() */ unsigned int drive_data; /* used by set_pio_mode/dev_select() */
unsigned int failures; /* current failure count */ unsigned int failures; /* current failure count */
unsigned int max_failures; /* maximum allowed failure count */ unsigned int max_failures; /* maximum allowed failure count */
u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */ u64 probed_capacity;/* initial/native media capacity */
u64 capacity64; /* total number of sectors */ u64 capacity64; /* total number of sectors */
int lun; /* logical unit */ int lun; /* logical unit */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment