diff options
Diffstat (limited to 'drivers/ide/ide-disk.c')
-rw-r--r-- | drivers/ide/ide-disk.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index dc2175c81f5e..4754769eda97 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -481,6 +481,16 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) && id->lba_capacity_2; } +/* + * Some disks report total number of sectors instead of + * maximum sector address. We list them here. + */ +static const struct drive_list_entry hpa_list[] = { + { "ST340823A", NULL }, + { "ST320413A", NULL }, + { NULL, NULL } +}; + static void idedisk_check_hpa(ide_drive_t *drive) { unsigned long long capacity, set_max; @@ -492,6 +502,15 @@ static void idedisk_check_hpa(ide_drive_t *drive) else set_max = idedisk_read_native_max_address(drive); + if (ide_in_drive_list(drive->id, hpa_list)) { + /* + * Since we are inclusive wrt to firmware revisions do this + * extra check and apply the workaround only when needed. + */ + if (set_max == capacity + 1) + set_max--; + } + if (set_max <= capacity) return; @@ -679,7 +698,7 @@ static ide_proc_entry_t idedisk_proc[] = { }; #endif /* CONFIG_IDE_PROC_FS */ -static void idedisk_prepare_flush(request_queue_t *q, struct request *rq) +static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) { ide_drive_t *drive = q->queuedata; @@ -697,7 +716,7 @@ static void idedisk_prepare_flush(request_queue_t *q, struct request *rq) rq->buffer = rq->cmd; } -static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk, +static int idedisk_issue_flush(struct request_queue *q, struct gendisk *disk, sector_t *error_sector) { ide_drive_t *drive = q->queuedata; @@ -1190,11 +1209,11 @@ static int idedisk_ioctl(struct inode *inode, struct file *file, return generic_ide_ioctl(drive, file, bdev, cmd, arg); read_val: - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); spin_lock_irqsave(&ide_lock, flags); err = *val; spin_unlock_irqrestore(&ide_lock, flags); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); return err >= 0 ? put_user(err, (long __user *)arg) : err; set_val: @@ -1204,9 +1223,9 @@ set_val: if (!capable(CAP_SYS_ADMIN)) err = -EACCES; else { - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); err = setfunc(drive, arg); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); } } return err; |