ide: add device flags

Add 'unsigned long dev_flags' to ide_drive_t and convert bitfields
to IDE_DFLAG_* flags.

While at it:
- IDE_DFLAG_ADDRESSING -> IDE_DFLAG_LBA48
- fixup some comments
- remove needless g->flags zeroing from ide*_probe()

There should be no functional changes caused by this patch.
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent be3c096e
...@@ -290,7 +290,7 @@ static int do_drive_get_GTF(ide_drive_t *drive, ...@@ -290,7 +290,7 @@ static int do_drive_get_GTF(ide_drive_t *drive,
DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
hwif->name, dev->bus_id, port, hwif->channel); hwif->name, dev->bus_id, port, hwif->channel);
if (!drive->present) { if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) {
DEBPRINT("%s drive %d:%d not present\n", DEBPRINT("%s drive %d:%d not present\n",
hwif->name, hwif->channel, port); hwif->name, hwif->channel, port);
goto out; goto out;
...@@ -420,8 +420,9 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, ...@@ -420,8 +420,9 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn); DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
if (!drive->present) if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
goto out; goto out;
if (!gtf_count) /* shouldn't be here */ if (!gtf_count) /* shouldn't be here */
goto out; goto out;
...@@ -660,7 +661,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) ...@@ -660,7 +661,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
if (!drive->acpidata->obj_handle) if (!drive->acpidata->obj_handle)
drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
if (drive->acpidata->obj_handle && drive->present) { if (drive->acpidata->obj_handle &&
(drive->dev_flags & IDE_DFLAG_PRESENT)) {
acpi_bus_set_power(drive->acpidata->obj_handle, acpi_bus_set_power(drive->acpidata->obj_handle,
on? ACPI_STATE_D0: ACPI_STATE_D3); on? ACPI_STATE_D0: ACPI_STATE_D3);
} }
...@@ -720,7 +722,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) ...@@ -720,7 +722,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
memset(drive->acpidata, 0, sizeof(*drive->acpidata)); memset(drive->acpidata, 0, sizeof(*drive->acpidata));
if (!drive->present) if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
continue; continue;
err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
...@@ -745,7 +747,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) ...@@ -745,7 +747,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
for (i = 0; i < MAX_DRIVES; i++) { for (i = 0; i < MAX_DRIVES; i++) {
drive = &hwif->drives[i]; drive = &hwif->drives[i];
if (drive->present) if (drive->dev_flags & IDE_DFLAG_PRESENT)
/* Execute ACPI startup code */ /* Execute ACPI startup code */
ide_acpi_exec_tfs(drive); ide_acpi_exec_tfs(drive);
} }
......
...@@ -261,7 +261,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -261,7 +261,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
ide_expiry_t *expiry; ide_expiry_t *expiry;
unsigned int timeout, temp; unsigned int timeout, temp;
u16 bcount; u16 bcount;
u8 stat, ireason, scsi = drive->scsi, dsc = 0; u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;
debug_log("Enter %s - interrupt handler\n", __func__); debug_log("Enter %s - interrupt handler\n", __func__);
...@@ -494,7 +494,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) ...@@ -494,7 +494,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
} }
ireason = ide_read_ireason(drive); ireason = ide_read_ireason(drive);
if (drive->media == ide_tape && !drive->scsi) if (drive->media == ide_tape &&
(drive->dev_flags & IDE_DFLAG_SCSI) == 0)
ireason = ide_wait_ireason(drive, ireason); ireason = ide_wait_ireason(drive, ireason);
if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
...@@ -512,7 +513,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) ...@@ -512,7 +513,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
timeout = drive->pc_delay; timeout = drive->pc_delay;
expiry = &ide_delayed_transfer_pc; expiry = &ide_delayed_transfer_pc;
} else { } else {
if (drive->scsi) { if (drive->dev_flags & IDE_DFLAG_SCSI) {
timeout = ide_scsi_get_timeout(pc); timeout = ide_scsi_get_timeout(pc);
expiry = ide_scsi_expiry; expiry = ide_scsi_expiry;
} else { } else {
...@@ -544,14 +545,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, ...@@ -544,14 +545,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
struct ide_atapi_pc *pc = drive->pc; struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
u16 bcount; u16 bcount;
u8 dma = 0; u8 dma = 0, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI);
/* We haven't transferred any data yet */ /* We haven't transferred any data yet */
pc->xferred = 0; pc->xferred = 0;
pc->cur_pos = pc->buf; pc->cur_pos = pc->buf;
/* Request to transfer the entire buffer at once */ /* Request to transfer the entire buffer at once */
if (drive->media == ide_tape && !drive->scsi) if (drive->media == ide_tape && scsi == 0)
bcount = pc->req_xfer; bcount = pc->req_xfer;
else else
bcount = min(pc->req_xfer, 63 * 1024); bcount = min(pc->req_xfer, 63 * 1024);
...@@ -561,19 +562,19 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, ...@@ -561,19 +562,19 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
ide_dma_off(drive); ide_dma_off(drive);
} }
if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { if ((pc->flags & PC_FLAG_DMA_OK) &&
if (drive->scsi) (drive->dev_flags & IDE_DFLAG_USING_DMA)) {
if (scsi)
hwif->sg_mapped = 1; hwif->sg_mapped = 1;
dma = !hwif->dma_ops->dma_setup(drive); dma = !hwif->dma_ops->dma_setup(drive);
if (drive->scsi) if (scsi)
hwif->sg_mapped = 0; hwif->sg_mapped = 0;
} }
if (!dma) if (!dma)
pc->flags &= ~PC_FLAG_DMA_OK; pc->flags &= ~PC_FLAG_DMA_OK;
ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, ide_pktcmd_tf_load(drive, scsi ? 0 : IDE_TFLAG_OUT_DEVICE, bcount, dma);
bcount, dma);
/* Issue the packet command */ /* Issue the packet command */
if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
......
...@@ -741,7 +741,7 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) ...@@ -741,7 +741,7 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
if (--retry == 0) if (--retry == 0)
drive->dsc_overlap = 0; drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
} }
return ide_stopped; return ide_stopped;
} }
...@@ -1129,7 +1129,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) ...@@ -1129,7 +1129,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
} }
cd->dma = 0; cd->dma = 0;
} else } else
cd->dma = drive->using_dma; cd->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
if (write) if (write)
cd->devinfo.media_written = 1; cd->devinfo.media_written = 1;
...@@ -1166,7 +1166,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) ...@@ -1166,7 +1166,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
else else
buf = rq->data; buf = rq->data;
info->dma = drive->using_dma; info->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
/* /*
* check if dma is safe * check if dma is safe
...@@ -1211,7 +1211,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, ...@@ -1211,7 +1211,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
if (rq_data_dir(rq) == READ && if (rq_data_dir(rq) == READ &&
IDE_LARGE_SEEK(info->last_block, block, IDE_LARGE_SEEK(info->last_block, block,
IDECD_SEEK_THRESHOLD) && IDECD_SEEK_THRESHOLD) &&
drive->dsc_overlap) { (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)) {
xferlen = 0; xferlen = 0;
fn = cdrom_start_seek_continuation; fn = cdrom_start_seek_continuation;
...@@ -1804,7 +1804,7 @@ static ide_proc_entry_t idecd_proc[] = { ...@@ -1804,7 +1804,7 @@ static ide_proc_entry_t idecd_proc[] = {
{ NULL, 0, NULL, NULL } { NULL, 0, NULL, NULL }
}; };
ide_devset_rw_field(dsc_overlap, dsc_overlap); ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP);
static const struct ide_proc_devset idecd_settings[] = { static const struct ide_proc_devset idecd_settings[] = {
IDE_PROC_DEVSET(dsc_overlap, 0, 1), IDE_PROC_DEVSET(dsc_overlap, 0, 1),
...@@ -1910,7 +1910,10 @@ static int ide_cdrom_setup(ide_drive_t *drive) ...@@ -1910,7 +1910,10 @@ static int ide_cdrom_setup(ide_drive_t *drive)
/* set correct block size */ /* set correct block size */
blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
drive->dsc_overlap = (drive->next != drive); if (drive->next != drive)
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
else
drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
if (ide_cdrom_register(drive, nslots)) { if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR "%s: %s failed to register device with the" printk(KERN_ERR "%s: %s failed to register device with the"
...@@ -1944,7 +1947,7 @@ static void ide_cd_release(struct kref *kref) ...@@ -1944,7 +1947,7 @@ static void ide_cd_release(struct kref *kref)
kfree(info->toc); kfree(info->toc);
if (devinfo->handle == drive) if (devinfo->handle == drive)
unregister_cdrom(devinfo); unregister_cdrom(devinfo);
drive->dsc_overlap = 0; drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
drive->driver_data = NULL; drive->driver_data = NULL;
blk_queue_prep_rq(drive->queue, NULL); blk_queue_prep_rq(drive->queue, NULL);
g->private_data = NULL; g->private_data = NULL;
......
...@@ -140,9 +140,9 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, ...@@ -140,9 +140,9 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
sector_t block) sector_t block)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
unsigned int dma = drive->using_dma;
u16 nsectors = (u16)rq->nr_sectors; u16 nsectors = (u16)rq->nr_sectors;
u8 lba48 = (drive->addressing == 1) ? 1 : 0; u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
ide_task_t task; ide_task_t task;
struct ide_taskfile *tf = &task.tf; struct ide_taskfile *tf = &task.tf;
ide_startstop_t rc; ide_startstop_t rc;
...@@ -237,7 +237,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, ...@@ -237,7 +237,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
BUG_ON(drive->blocked); BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED);
if (!blk_fs_request(rq)) { if (!blk_fs_request(rq)) {
blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
...@@ -452,7 +452,7 @@ static int proc_idedisk_read_cache ...@@ -452,7 +452,7 @@ static int proc_idedisk_read_cache
char *out = page; char *out = page;
int len; int len;
if (drive->id_read) if (drive->dev_flags & IDE_DFLAG_ID_READ)
len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
else else
len = sprintf(out, "(none)\n"); len = sprintf(out, "(none)\n");
...@@ -568,15 +568,20 @@ static int set_multcount(ide_drive_t *drive, int arg) ...@@ -568,15 +568,20 @@ static int set_multcount(ide_drive_t *drive, int arg)
return (drive->mult_count == arg) ? 0 : -EIO; return (drive->mult_count == arg) ? 0 : -EIO;
} }
ide_devset_get(nowerr, nowerr); ide_devset_get_flag(nowerr, IDE_DFLAG_NOWERR);
static int set_nowerr(ide_drive_t *drive, int arg) static int set_nowerr(ide_drive_t *drive, int arg)
{ {
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
return -EINVAL; return -EINVAL;
drive->nowerr = arg; if (arg)
drive->dev_flags |= IDE_DFLAG_NOWERR;
else
drive->dev_flags &= ~IDE_DFLAG_NOWERR;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
return 0; return 0;
} }
...@@ -599,7 +604,7 @@ static void update_ordered(ide_drive_t *drive) ...@@ -599,7 +604,7 @@ static void update_ordered(ide_drive_t *drive)
unsigned ordered = QUEUE_ORDERED_NONE; unsigned ordered = QUEUE_ORDERED_NONE;
prepare_flush_fn *prep_fn = NULL; prepare_flush_fn *prep_fn = NULL;
if (drive->wcache) { if (drive->dev_flags & IDE_DFLAG_WCACHE) {
unsigned long long capacity; unsigned long long capacity;
int barrier; int barrier;
/* /*
...@@ -611,8 +616,10 @@ static void update_ordered(ide_drive_t *drive) ...@@ -611,8 +616,10 @@ static void update_ordered(ide_drive_t *drive)
* not available so we don't need to recheck that. * not available so we don't need to recheck that.
*/ */
capacity = idedisk_capacity(drive); capacity = idedisk_capacity(drive);
barrier = ata_id_flush_enabled(id) && !drive->noflush && barrier = ata_id_flush_enabled(id) &&
(drive->addressing == 0 || capacity <= (1ULL << 28) || (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 &&
((drive->dev_flags & IDE_DFLAG_LBA48) == 0 ||
capacity <= (1ULL << 28) ||
ata_id_flush_ext_enabled(id)); ata_id_flush_ext_enabled(id));
printk(KERN_INFO "%s: cache flushes %ssupported\n", printk(KERN_INFO "%s: cache flushes %ssupported\n",
...@@ -628,7 +635,7 @@ static void update_ordered(ide_drive_t *drive) ...@@ -628,7 +635,7 @@ static void update_ordered(ide_drive_t *drive)
blk_queue_ordered(drive->queue, ordered, prep_fn); blk_queue_ordered(drive->queue, ordered, prep_fn);
} }
ide_devset_get(wcache, wcache); ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE);
static int set_wcache(ide_drive_t *drive, int arg) static int set_wcache(ide_drive_t *drive, int arg)
{ {
...@@ -640,8 +647,12 @@ static int set_wcache(ide_drive_t *drive, int arg) ...@@ -640,8 +647,12 @@ static int set_wcache(ide_drive_t *drive, int arg)
if (ata_id_flush_enabled(drive->id)) { if (ata_id_flush_enabled(drive->id)) {
err = ide_do_setfeature(drive, err = ide_do_setfeature(drive,
arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF, 0); arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF, 0);
if (err == 0) if (err == 0) {
drive->wcache = arg; if (arg)
drive->dev_flags |= IDE_DFLAG_WCACHE;
else
drive->dev_flags &= ~IDE_DFLAG_WCACHE;
}
} }
update_ordered(drive); update_ordered(drive);
...@@ -677,7 +688,7 @@ static int set_acoustic(ide_drive_t *drive, int arg) ...@@ -677,7 +688,7 @@ static int set_acoustic(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(addressing, addressing); ide_devset_get_flag(addressing, IDE_DFLAG_LBA48);
/* /*
* drive->addressing: * drive->addressing:
...@@ -697,7 +708,10 @@ static int set_addressing(ide_drive_t *drive, int arg) ...@@ -697,7 +708,10 @@ static int set_addressing(ide_drive_t *drive, int arg)
if (arg == 2) if (arg == 2)
arg = 0; arg = 0;
drive->addressing = arg; if (arg)
drive->dev_flags |= IDE_DFLAG_LBA48;
else
drive->dev_flags &= ~IDE_DFLAG_LBA48;
return 0; return 0;
} }
...@@ -743,20 +757,20 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -743,20 +757,20 @@ static void idedisk_setup(ide_drive_t *drive)
ide_proc_register_driver(drive, idkp->driver); ide_proc_register_driver(drive, idkp->driver);
if (drive->id_read == 0) if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0)
return; return;
if (drive->removable) { if (drive->dev_flags & IDE_DFLAG_REMOVABLE) {
/* /*
* Removable disks (eg. SYQUEST); ignore 'WD' drives * Removable disks (eg. SYQUEST); ignore 'WD' drives
*/ */
if (m[0] != 'W' || m[1] != 'D') if (m[0] != 'W' || m[1] != 'D')
drive->doorlocking = 1; drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
} }
(void)set_addressing(drive, 1); (void)set_addressing(drive, 1);
if (drive->addressing == 1) { if (drive->dev_flags & IDE_DFLAG_LBA48) {
int max_s = 2048; int max_s = 2048;
if (max_s > hwif->rqsize) if (max_s > hwif->rqsize)
...@@ -772,7 +786,8 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -772,7 +786,8 @@ static void idedisk_setup(ide_drive_t *drive)
init_idedisk_capacity(drive); init_idedisk_capacity(drive);
/* limit drive capacity to 137GB if LBA48 cannot be used */ /* limit drive capacity to 137GB if LBA48 cannot be used */
if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) { if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
drive->capacity64 > 1ULL << 28) {
printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
"%llu sectors (%llu MB)\n", "%llu sectors (%llu MB)\n",
drive->name, (unsigned long long)drive->capacity64, drive->name, (unsigned long long)drive->capacity64,
...@@ -780,13 +795,14 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -780,13 +795,14 @@ static void idedisk_setup(ide_drive_t *drive)
drive->capacity64 = 1ULL << 28; drive->capacity64 = 1ULL << 28;
} }
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) { if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
(drive->dev_flags & IDE_DFLAG_LBA48)) {
if (drive->capacity64 > 1ULL << 28) { if (drive->capacity64 > 1ULL << 28) {
printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
" will be used for accessing sectors " " will be used for accessing sectors "
"> %u\n", drive->name, 1 << 28); "> %u\n", drive->name, 1 << 28);
} else } else
drive->addressing = 0; drive->dev_flags &= ~IDE_DFLAG_LBA48;
} }
/* /*
...@@ -795,7 +811,7 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -795,7 +811,7 @@ static void idedisk_setup(ide_drive_t *drive)
*/ */
capacity = idedisk_capacity(drive); capacity = idedisk_capacity(drive);
if (!drive->forced_geom) { if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) {
if (ata_id_lba48_enabled(drive->id)) { if (ata_id_lba48_enabled(drive->id)) {
/* compatibility */ /* compatibility */
drive->bios_sect = 63; drive->bios_sect = 63;
...@@ -830,14 +846,15 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -830,14 +846,15 @@ static void idedisk_setup(ide_drive_t *drive)
/* write cache enabled? */ /* write cache enabled? */
if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id)) if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id))
drive->wcache = 1; drive->dev_flags |= IDE_DFLAG_WCACHE;
set_wcache(drive, 1); set_wcache(drive, 1);
} }
static void ide_cacheflush_p(ide_drive_t *drive) static void ide_cacheflush_p(ide_drive_t *drive)
{ {
if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) if (ata_id_flush_enabled(drive->id) == 0 ||
(drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
return; return;
if (do_idedisk_flushcache(drive)) if (do_idedisk_flushcache(drive))
...@@ -956,15 +973,16 @@ static int idedisk_open(struct inode *inode, struct file *filp) ...@@ -956,15 +973,16 @@ static int idedisk_open(struct inode *inode, struct file *filp)
idkp->openers++; idkp->openers++;
if (drive->removable && idkp->openers == 1) { if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
check_disk_change(inode->i_bdev); check_disk_change(inode->i_bdev);
/* /*
* Ignore the return code from door_lock, * Ignore the return code from door_lock,
* since the open() has already succeeded, * since the open() has already succeeded,
* and the door_lock is irrelevant at this point. * and the door_lock is irrelevant at this point.
*/ */
if (drive->doorlocking && idedisk_set_doorlock(drive, 1)) if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
drive->doorlocking = 0; idedisk_set_doorlock(drive, 1))
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
} }
return 0; return 0;
} }
...@@ -978,9 +996,10 @@ static int idedisk_release(struct inode *inode, struct file *filp) ...@@ -978,9 +996,10 @@ static int idedisk_release(struct inode *inode, struct file *filp)
if (idkp->openers == 1) if (idkp->openers == 1)
ide_cacheflush_p(drive); ide_cacheflush_p(drive);
if (drive->removable && idkp->openers == 1) { if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
if (drive->doorlocking && idedisk_set_doorlock(drive, 0)) if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
drive->doorlocking = 0; idedisk_set_doorlock(drive, 0))
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
} }
idkp->openers--; idkp->openers--;
...@@ -1031,12 +1050,13 @@ static int idedisk_media_changed(struct gendisk *disk) ...@@ -1031,12 +1050,13 @@ static int idedisk_media_changed(struct gendisk *disk)
ide_drive_t *drive = idkp->drive; ide_drive_t *drive = idkp->drive;
/* do not scan partitions twice if this is a removable device */ /* do not scan partitions twice if this is a removable device */
if (drive->attach) { if (drive->dev_flags & IDE_DFLAG_ATTACH) {
drive->attach = 0; drive->dev_flags &= ~IDE_DFLAG_ATTACH;
return 0; return 0;
} }
/* if removable, always assume it was changed */ /* if removable, always assume it was changed */
return drive->removable; return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE);
} }
static int idedisk_revalidate_disk(struct gendisk *disk) static int idedisk_revalidate_disk(struct gendisk *disk)
...@@ -1094,15 +1114,15 @@ static int ide_disk_probe(ide_drive_t *drive) ...@@ -1094,15 +1114,15 @@ static int ide_disk_probe(ide_drive_t *drive)
if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
drive->name, drive->head); drive->name, drive->head);
drive->attach = 0; drive->dev_flags &= ~IDE_DFLAG_ATTACH;
} else } else
drive->attach = 1; drive->dev_flags |= IDE_DFLAG_ATTACH;
g->minors = IDE_DISK_MINORS; g->minors = IDE_DISK_MINORS;
g->driverfs_dev = &drive->gendev; g->driverfs_dev = &drive->gendev;
g->flags |= GENHD_FL_EXT_DEVT; g->flags |= GENHD_FL_EXT_DEVT;
if (drive->removable) if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
g->flags |= GENHD_FL_REMOVABLE; g->flags = GENHD_FL_REMOVABLE;
set_capacity(g, idedisk_capacity(drive)); set_capacity(g, idedisk_capacity(drive));
g->fops = &idedisk_ops; g->fops = &idedisk_ops;
add_disk(g); add_disk(g);
......
...@@ -397,7 +397,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set); ...@@ -397,7 +397,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
void ide_dma_off_quietly(ide_drive_t *drive) void ide_dma_off_quietly(ide_drive_t *drive)
{ {
drive->using_dma = 0; drive->dev_flags &= ~IDE_DFLAG_USING_DMA;
ide_toggle_bounce(drive, 0); ide_toggle_bounce(drive, 0);
drive->hwif->dma_ops->dma_host_set(drive, 0); drive->hwif->dma_ops->dma_host_set(drive, 0);
...@@ -430,7 +430,7 @@ EXPORT_SYMBOL(ide_dma_off); ...@@ -430,7 +430,7 @@ EXPORT_SYMBOL(ide_dma_off);
void ide_dma_on(ide_drive_t *drive) void ide_dma_on(ide_drive_t *drive)
{ {
drive->using_dma = 1; drive->dev_flags |= IDE_DFLAG_USING_DMA;
ide_toggle_bounce(drive, 1); ide_toggle_bounce(drive, 1);
drive->hwif->dma_ops->dma_host_set(drive, 1); drive->hwif->dma_ops->dma_host_set(drive, 1);
...@@ -727,7 +727,8 @@ static int ide_tune_dma(ide_drive_t *drive) ...@@ -727,7 +727,8 @@ static int ide_tune_dma(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
u8 speed; u8 speed;
if (drive->nodma || ata_id_has_dma(drive->id) == 0) if (ata_id_has_dma(drive->id) == 0 ||
(drive->dev_flags & IDE_DFLAG_NODMA))
return 0; return 0;
/* consult the list of known "bad" drives */ /* consult the list of known "bad" drives */
......
...@@ -828,8 +828,8 @@ static int idefloppy_media_changed(struct gendisk *disk) ...@@ -828,8 +828,8 @@ static int idefloppy_media_changed(struct gendisk *disk)
int ret; int ret;
/* do not scan partitions twice if this is a removable device */ /* do not scan partitions twice if this is a removable device */
if (drive->attach) { if (drive->dev_flags & IDE_DFLAG_ATTACH) {
drive->attach = 0; drive->dev_flags &= ~IDE_DFLAG_ATTACH;
return 0; return 0;
} }
ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED);
...@@ -896,12 +896,13 @@ static int ide_floppy_probe(ide_drive_t *drive) ...@@ -896,12 +896,13 @@ static int ide_floppy_probe(ide_drive_t *drive)
drive->debug_mask = debug_mask; drive->debug_mask = debug_mask;
idefloppy_setup(drive, floppy); idefloppy_setup(drive, floppy);
drive->dev_flags |= IDE_DFLAG_ATTACH;
g->minors = 1 << PARTN_BITS; g->minors = 1 << PARTN_BITS;
g->driverfs_dev = &drive->gendev; g->driverfs_dev = &drive->gendev;
g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
g->flags = GENHD_FL_REMOVABLE;
g->fops = &idefloppy_ops; g->fops = &idefloppy_ops;
drive->attach = 1;
add_disk(g); add_disk(g);
return 0; return 0;
......
...@@ -184,7 +184,8 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * ...@@ -184,7 +184,8 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
if (drive->media != ide_disk) if (drive->media != ide_disk)
break; break;
/* Not supported? Switch to next step now. */ /* Not supported? Switch to next step now. */
if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) { if (ata_id_flush_enabled(drive->id) == 0 ||
(drive->dev_flags & IDE_DFLAG_WCACHE) == 0) {
ide_complete_power_step(drive, rq, 0, 0); ide_complete_power_step(drive, rq, 0, 0);
return ide_stopped; return ide_stopped;
} }
...@@ -222,7 +223,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * ...@@ -222,7 +223,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
if (drive->hwif->dma_ops == NULL) if (drive->hwif->dma_ops == NULL)
break; break;
/* /*
* TODO: respect ->using_dma setting * TODO: respect IDE_DFLAG_USING_DMA
*/ */
ide_set_dma(drive); ide_set_dma(drive);
break; break;
...@@ -287,7 +288,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) ...@@ -287,7 +288,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
if (blk_pm_suspend_request(rq)) { if (blk_pm_suspend_request(rq)) {
blk_stop_queue(drive->queue); blk_stop_queue(drive->queue);
} else { } else {
drive->blocked = 0; drive->dev_flags &= ~IDE_DFLAG_BLOCKED;
blk_start_queue(drive->queue); blk_start_queue(drive->queue);
} }
HWGROUP(drive)->rq = NULL; HWGROUP(drive)->rq = NULL;
...@@ -374,7 +375,8 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 ...@@ -374,7 +375,8 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { if ((stat & ATA_BUSY) ||
((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
/* other bits are useless when BUSY */ /* other bits are useless when BUSY */
rq->errors |= ERROR_RESET; rq->errors |= ERROR_RESET;
} else if (stat & ATA_ERR) { } else if (stat & ATA_ERR) {
...@@ -428,7 +430,8 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u ...@@ -428,7 +430,8 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { if ((stat & ATA_BUSY) ||
((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
/* other bits are useless when BUSY */ /* other bits are useless when BUSY */
rq->errors |= ERROR_RESET; rq->errors |= ERROR_RESET;
} else { } else {
...@@ -607,7 +610,7 @@ static ide_startstop_t do_special (ide_drive_t *drive) ...@@ -607,7 +610,7 @@ static ide_startstop_t do_special (ide_drive_t *drive)
if (set_pio_mode_abuse(drive->hwif, req_pio)) { if (set_pio_mode_abuse(drive->hwif, req_pio)) {
/* /*
* take ide_lock for drive->[no_]unmask/[no_]io_32bit * take ide_lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT
*/ */
if (req_pio == 8 || req_pio == 9) { if (req_pio == 8 || req_pio == 9) {
unsigned long flags; unsigned long flags;
...@@ -618,7 +621,8 @@ static ide_startstop_t do_special (ide_drive_t *drive) ...@@ -618,7 +621,8 @@ static ide_startstop_t do_special (ide_drive_t *drive)
} else } else
port_ops->set_pio_mode(drive, req_pio); port_ops->set_pio_mode(drive, req_pio);
} else { } else {
int keep_dma = drive->using_dma; int keep_dma =
!!(drive->dev_flags & IDE_DFLAG_USING_DMA);
ide_set_pio(drive, req_pio); ide_set_pio(drive, req_pio);
...@@ -775,7 +779,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) ...@@ -775,7 +779,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
if (blk_pm_suspend_request(rq) && if (blk_pm_suspend_request(rq) &&
pm->pm_step == ide_pm_state_start_suspend) pm->pm_step == ide_pm_state_start_suspend)
/* Mark drive blocked when starting the suspend sequence. */ /* Mark drive blocked when starting the suspend sequence. */
drive->blocked = 1; drive->dev_flags |= IDE_DFLAG_BLOCKED;
else if (blk_pm_resume_request(rq) && else if (blk_pm_resume_request(rq) &&
pm->pm_step == ide_pm_state_start_resume) { pm->pm_step == ide_pm_state_start_resume) {
/* /*
...@@ -895,7 +899,7 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) ...@@ -895,7 +899,7 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
if (timeout > WAIT_WORSTCASE) if (timeout > WAIT_WORSTCASE)
timeout = WAIT_WORSTCASE; timeout = WAIT_WORSTCASE;
drive->sleep = timeout + jiffies; drive->sleep = timeout + jiffies;
drive->sleeping = 1; drive->dev_flags |= IDE_DFLAG_SLEEPING;
} }
EXPORT_SYMBOL(ide_stall_queue); EXPORT_SYMBOL(ide_stall_queue);
...@@ -935,18 +939,23 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) ...@@ -935,18 +939,23 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
} }
do { do {
if ((!drive->sleeping || time_after_eq(jiffies, drive->sleep)) u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING);
&& !elv_queue_empty(drive->queue)) { u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING));
if (!best
|| (drive->sleeping && (!best->sleeping || time_before(drive->sleep, best->sleep))) if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) &&
|| (!best->sleeping && time_before(WAKEUP(drive), WAKEUP(best)))) !elv_queue_empty(drive->queue)) {
{ if (best == NULL ||
(dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) ||
(best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) {
if (!blk_queue_plugged(drive->queue)) if (!blk_queue_plugged(drive->queue))
best = drive; best = drive;
} }
} }
} while ((drive = drive->next) != hwgroup->drive); } while ((drive = drive->next) != hwgroup->drive);
if (best && best->nice1 && !best->sleeping && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
if (best && (best->dev_flags & IDE_DFLAG_NICE1) &&
(best->dev_flags & IDE_DFLAG_SLEEPING) == 0 &&
best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
long t = (signed long)(WAKEUP(best) - jiffies); long t = (signed long)(WAKEUP(best) - jiffies);
if (t >= WAIT_MIN_SLEEP) { if (t >= WAIT_MIN_SLEEP) {
/* /*
...@@ -955,7 +964,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) ...@@ -955,7 +964,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
*/ */
drive = best->next; drive = best->next;
do { do {
if (!drive->sleeping if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0
&& time_before(jiffies - best->service_time, WAKEUP(drive)) && time_before(jiffies - best->service_time, WAKEUP(drive))
&& time_before(WAKEUP(drive), jiffies + t)) && time_before(WAKEUP(drive), jiffies + t))
{ {
...@@ -1026,7 +1035,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1026,7 +1035,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
hwgroup->rq = NULL; hwgroup->rq = NULL;
drive = hwgroup->drive; drive = hwgroup->drive;
do { do {
if (drive->sleeping && (!sleeping || time_before(drive->sleep, sleep))) { if ((drive->dev_flags & IDE_DFLAG_SLEEPING) &&
(sleeping == 0 ||
time_before(drive->sleep, sleep))) {
sleeping = 1; sleeping = 1;
sleep = drive->sleep; sleep = drive->sleep;
} }
...@@ -1075,7 +1086,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1075,7 +1086,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
} }
hwgroup->hwif = hwif; hwgroup->hwif = hwif;
hwgroup->drive = drive; hwgroup->drive = drive;
drive->sleeping = 0; drive->dev_flags &= ~IDE_DFLAG_SLEEPING;
drive->service_start = jiffies; drive->service_start = jiffies;
if (blk_queue_plugged(drive->queue)) { if (blk_queue_plugged(drive->queue)) {
...@@ -1109,7 +1120,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1109,7 +1120,9 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
* We count how many times we loop here to make sure we service * We count how many times we loop here to make sure we service
* all drives in the hwgroup without looping for ever * all drives in the hwgroup without looping for ever
*/ */
if (drive->blocked && !blk_pm_request(rq) && !(rq->cmd_flags & REQ_PREEMPT)) { if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
blk_pm_request(rq) == 0 &&
(rq->cmd_flags & REQ_PREEMPT) == 0) {
drive = drive->next ? drive->next : hwgroup->drive; drive = drive->next ? drive->next : hwgroup->drive;
if (loops++ < 4 && !blk_queue_plugged(drive->queue)) if (loops++ < 4 && !blk_queue_plugged(drive->queue))
goto again; goto again;
...@@ -1491,7 +1504,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) ...@@ -1491,7 +1504,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
*/ */
hwif->ide_dma_clear_irq(drive); hwif->ide_dma_clear_irq(drive);
if (drive->unmask) if (drive->dev_flags & IDE_DFLAG_UNMASK)
local_irq_enable_in_hardirq(); local_irq_enable_in_hardirq();
/* service this interrupt, may set handler for next interrupt */ /* service this interrupt, may set handler for next interrupt */
startstop = handler(drive); startstop = handler(drive);
......
...@@ -62,7 +62,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, ...@@ -62,7 +62,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd,
int size = (cmd == HDIO_GET_IDENTITY) ? (ATA_ID_WORDS * 2) : 142; int size = (cmd == HDIO_GET_IDENTITY) ? (ATA_ID_WORDS * 2) : 142;
int rc = 0; int rc = 0;
if (drive->id_read == 0) { if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
rc = -ENOMSG; rc = -ENOMSG;
goto out; goto out;
} }
...@@ -86,8 +86,10 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, ...@@ -86,8 +86,10 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd,
static int ide_get_nice_ioctl(ide_drive_t *drive, unsigned long arg) static int ide_get_nice_ioctl(ide_drive_t *drive, unsigned long arg)
{ {
return put_user((drive->dsc_overlap << IDE_NICE_DSC_OVERLAP) | return put_user((!!(drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)
(drive->nice1 << IDE_NICE_1), (long __user *)arg); << IDE_NICE_DSC_OVERLAP) |
(!!(drive->dev_flags & IDE_DFLAG_NICE1)
<< IDE_NICE_1), (long __user *)arg);
} }
static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
...@@ -97,11 +99,18 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -97,11 +99,18 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) &&
(drive->media == ide_disk || drive->media == ide_floppy || (drive->media == ide_disk || drive->media == ide_floppy ||
drive->scsi)) (drive->dev_flags & IDE_DFLAG_SCSI)))
return -EPERM; return -EPERM;
drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; if ((arg >> IDE_NICE_DSC_OVERLAP) & 1)
drive->nice1 = (arg >> IDE_NICE_1) & 1; drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
else
drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
if ((arg >> IDE_NICE_1) & 1)
drive->dev_flags |= IDE_DFLAG_NICE1;
else
drive->dev_flags &= ~IDE_DFLAG_NICE1;
return 0; return 0;
} }
......
...@@ -647,7 +647,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) ...@@ -647,7 +647,7 @@ u8 eighty_ninty_three (ide_drive_t *drive)
return 1; return 1;
no_80w: no_80w:
if (drive->udma33_warned == 1) if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED)
return 0; return 0;
printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
...@@ -655,7 +655,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) ...@@ -655,7 +655,7 @@ u8 eighty_ninty_three (ide_drive_t *drive)
drive->name, drive->name,
hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host");
drive->udma33_warned = 1; drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED;
return 0; return 0;
} }
...@@ -711,7 +711,7 @@ int ide_driveid_update(ide_drive_t *drive) ...@@ -711,7 +711,7 @@ int ide_driveid_update(ide_drive_t *drive)
kfree(id); kfree(id);
if (drive->using_dma && ide_id_dma_bug(drive)) if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive))
ide_dma_off(drive); ide_dma_off(drive);
return 1; return 1;
...@@ -790,7 +790,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -790,7 +790,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
skip: skip:
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0 && drive->using_dma) if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA))
hwif->dma_ops->dma_host_set(drive, 1); hwif->dma_ops->dma_host_set(drive, 1);
else if (hwif->dma_ops) /* check if host supports DMA */ else if (hwif->dma_ops) /* check if host supports DMA */
ide_dma_off_quietly(drive); ide_dma_off_quietly(drive);
...@@ -1016,9 +1016,13 @@ static void ide_disk_pre_reset(ide_drive_t *drive) ...@@ -1016,9 +1016,13 @@ static void ide_disk_pre_reset(ide_drive_t *drive)
drive->special.all = 0; drive->special.all = 0;
drive->special.b.set_geometry = legacy; drive->special.b.set_geometry = legacy;
drive->special.b.recalibrate = legacy; drive->special.b.recalibrate = legacy;
drive->mult_count = 0; drive->mult_count = 0;
if (!drive->keep_settings && !drive->using_dma)
if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
(drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
drive->mult_req = 0; drive->mult_req = 0;
if (drive->mult_req != drive->mult_count) if (drive->mult_req != drive->mult_count)
drive->special.b.set_multmode = 1; drive->special.b.set_multmode = 1;
} }
...@@ -1030,18 +1034,18 @@ static void pre_reset(ide_drive_t *drive) ...@@ -1030,18 +1034,18 @@ static void pre_reset(ide_drive_t *drive)
if (drive->media == ide_disk) if (drive->media == ide_disk)
ide_disk_pre_reset(drive); ide_disk_pre_reset(drive);
else else
drive->post_reset = 1; drive->dev_flags |= IDE_DFLAG_POST_RESET;
if (drive->using_dma) { if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
if (drive->crc_count) if (drive->crc_count)
ide_check_dma_crc(drive); ide_check_dma_crc(drive);
else else
ide_dma_off(drive); ide_dma_off(drive);
} }
if (!drive->keep_settings) { if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
if (!drive->using_dma) { if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
drive->unmask = 0; drive->dev_flags &= ~IDE_DFLAG_UNMASK;
drive->io_32bit = 0; drive->io_32bit = 0;
} }
return; return;
......
...@@ -317,7 +317,7 @@ static void ide_dump_sector(ide_drive_t *drive) ...@@ -317,7 +317,7 @@ static void ide_dump_sector(ide_drive_t *drive)
{ {
ide_task_t task; ide_task_t task;
struct ide_taskfile *tf = &task.tf; struct ide_taskfile *tf = &task.tf;
int lba48 = (drive->addressing == 1) ? 1 : 0; u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
memset(&task, 0, sizeof(task)); memset(&task, 0, sizeof(task));
if (lba48) if (lba48)
......
This diff is collapsed.
...@@ -227,7 +227,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) ...@@ -227,7 +227,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
ide_devset_rw(current_speed, xfer_rate); ide_devset_rw(current_speed, xfer_rate);
ide_devset_rw_field(init_speed, init_speed); ide_devset_rw_field(init_speed, init_speed);
ide_devset_rw_field(nice1, nice1); ide_devset_rw_flag(nice1, IDE_DFLAG_NICE1);
ide_devset_rw_field(number, dn); ide_devset_rw_field(number, dn);
static const struct ide_proc_devset ide_generic_settings[] = { static const struct ide_proc_devset ide_generic_settings[] = {
...@@ -622,9 +622,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif) ...@@ -622,9 +622,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
for (d = 0; d < MAX_DRIVES; d++) { for (d = 0; d < MAX_DRIVES; d++) {
ide_drive_t *drive = &hwif->drives[d]; ide_drive_t *drive = &hwif->drives[d];
if (!drive->present) if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc)
continue;
if (drive->proc)
continue; continue;
drive->proc = proc_mkdir(drive->name, parent); drive->proc = proc_mkdir(drive->name, parent);
......
...@@ -826,12 +826,13 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, ...@@ -826,12 +826,13 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
*/ */
stat = hwif->tp_ops->read_status(hwif); stat = hwif->tp_ops->read_status(hwif);
if (!drive->dsc_overlap && !(rq->cmd[13] & REQ_IDETAPE_PC2)) if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 &&
(rq->cmd[13] & REQ_IDETAPE_PC2) == 0)
set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
if (drive->post_reset == 1) { if (drive->dev_flags & IDE_DFLAG_POST_RESET) {
set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
drive->post_reset = 0; drive->dev_flags &= ~IDE_DFLAG_POST_RESET;
} }
if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) &&
...@@ -1354,7 +1355,7 @@ static int idetape_init_read(ide_drive_t *drive) ...@@ -1354,7 +1355,7 @@ static int idetape_init_read(ide_drive_t *drive)
* No point in issuing this if DSC overlap isn't supported, some * No point in issuing this if DSC overlap isn't supported, some
* drives (Seagate STT3401A) will return an error. * drives (Seagate STT3401A) will return an error.
*/ */
if (drive->dsc_overlap) { if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
bytes_read = idetape_queue_rw_tail(drive, bytes_read = idetape_queue_rw_tail(drive,
REQ_IDETAPE_READ, 0, REQ_IDETAPE_READ, 0,
tape->merge_bh); tape->merge_bh);
...@@ -1630,7 +1631,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ...@@ -1630,7 +1631,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
* point in issuing this if DSC overlap isn't supported, some * point in issuing this if DSC overlap isn't supported, some
* drives (Seagate STT3401A) will return an error. * drives (Seagate STT3401A) will return an error.
*/ */
if (drive->dsc_overlap) { if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
ssize_t retval = idetape_queue_rw_tail(drive, ssize_t retval = idetape_queue_rw_tail(drive,
REQ_IDETAPE_WRITE, 0, REQ_IDETAPE_WRITE, 0,
tape->merge_bh); tape->merge_bh);
...@@ -2145,7 +2146,7 @@ static int divf_tdsc(ide_drive_t *drive) { return HZ; } ...@@ -2145,7 +2146,7 @@ static int divf_tdsc(ide_drive_t *drive) { return HZ; }
static int divf_buffer(ide_drive_t *drive) { return 2; } static int divf_buffer(ide_drive_t *drive) { return 2; }
static int divf_buffer_size(ide_drive_t *drive) { return 1024; } static int divf_buffer_size(ide_drive_t *drive) { return 1024; }
ide_devset_rw_field(dsc_overlap, dsc_overlap); ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP);
ide_tape_devset_rw_field(debug_mask, debug_mask); ide_tape_devset_rw_field(debug_mask, debug_mask);
ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);
...@@ -2192,15 +2193,19 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -2192,15 +2193,19 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
drive->pc_io_buffers = ide_tape_io_buffers; drive->pc_io_buffers = ide_tape_io_buffers;
spin_lock_init(&tape->lock); spin_lock_init(&tape->lock);
drive->dsc_overlap = 1;
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n",
tape->name); tape->name);
drive->dsc_overlap = 0; drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
} }
/* Seagate Travan drives do not support DSC overlap. */ /* Seagate Travan drives do not support DSC overlap. */
if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401")) if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401"))
drive->dsc_overlap = 0; drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
tape->minor = minor; tape->minor = minor;
tape->name[0] = 'h'; tape->name[0] = 'h';
tape->name[1] = 't'; tape->name[1] = 't';
...@@ -2247,7 +2252,7 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -2247,7 +2252,7 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
(*(u16 *)&tape->caps[16] * 512) / tape->buffer_size, (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size,
tape->buffer_size / 1024, tape->buffer_size / 1024,
tape->best_dsc_rw_freq * 1000 / HZ, tape->best_dsc_rw_freq * 1000 / HZ,
drive->using_dma ? ", DMA":""); (drive->dev_flags & IDE_DFLAG_USING_DMA) ? ", DMA" : "");
ide_proc_register_driver(drive, tape->driver); ide_proc_register_driver(drive, tape->driver);
} }
...@@ -2271,7 +2276,7 @@ static void ide_tape_release(struct kref *kref) ...@@ -2271,7 +2276,7 @@ static void ide_tape_release(struct kref *kref)
BUG_ON(tape->merge_bh_size); BUG_ON(tape->merge_bh_size);
drive->dsc_overlap = 0; drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
drive->driver_data = NULL; drive->driver_data = NULL;
device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor));
device_destroy(idetape_sysfs_class, device_destroy(idetape_sysfs_class,
...@@ -2386,7 +2391,8 @@ static int ide_tape_probe(ide_drive_t *drive) ...@@ -2386,7 +2391,8 @@ static int ide_tape_probe(ide_drive_t *drive)
if (drive->media != ide_tape) if (drive->media != ide_tape)
goto failed; goto failed;
if (drive->id_read == 1 && !ide_check_atapi_device(drive, DRV_NAME)) { if ((drive->dev_flags & IDE_DFLAG_ID_READ) &&
ide_check_atapi_device(drive, DRV_NAME) == 0) {
printk(KERN_ERR "ide-tape: %s: not supported by this version of" printk(KERN_ERR "ide-tape: %s: not supported by this version of"
" the driver\n", drive->name); " the driver\n", drive->name);
goto failed; goto failed;
......
...@@ -116,7 +116,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -116,7 +116,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
WAIT_WORSTCASE, NULL); WAIT_WORSTCASE, NULL);
return ide_started; return ide_started;
default: default:
if (drive->using_dma == 0 || dma_ops->dma_setup(drive)) if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
dma_ops->dma_setup(drive))
return ide_stopped; return ide_stopped;
dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_exec_cmd(drive, tf->command);
dma_ops->dma_start(drive); dma_ops->dma_start(drive);
...@@ -469,13 +470,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) ...@@ -469,13 +470,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
if (ide_wait_stat(&startstop, drive, ATA_DRQ, if (ide_wait_stat(&startstop, drive, ATA_DRQ,
drive->bad_wstat, WAIT_DRQ)) { drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
drive->name, drive->name, drive->hwif->data_phase ? "MULT" : "",
drive->hwif->data_phase ? "MULT" : "", (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
drive->addressing ? "_EXT" : "");
return startstop; return startstop;
} }
if (!drive->unmask) if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
local_irq_disable(); local_irq_disable();
ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
...@@ -591,7 +591,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -591,7 +591,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
IDE_TFLAG_IN_TF; IDE_TFLAG_IN_TF;
if (drive->addressing == 1) if (drive->dev_flags & IDE_DFLAG_LBA48)
args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
if (req_task->out_flags.all) { if (req_task->out_flags.all) {
...@@ -694,7 +694,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -694,7 +694,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) && if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
req_task->in_flags.all == 0) { req_task->in_flags.all == 0) {
req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->addressing == 1) if (drive->dev_flags & IDE_DFLAG_LBA48)
req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
} }
......
...@@ -138,7 +138,7 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif) ...@@ -138,7 +138,7 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif)
for (i = 0; i < MAX_DRIVES; i++) { for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[i]; ide_drive_t *drive = &hwif->drives[i];
if (drive->present) { if (drive->dev_flags & IDE_DFLAG_PRESENT) {
spin_unlock_irq(&ide_lock); spin_unlock_irq(&ide_lock);
device_unregister(&drive->gendev); device_unregister(&drive->gendev);
wait_for_completion(&drive->gendev_rel_comp); wait_for_completion(&drive->gendev_rel_comp);
...@@ -254,7 +254,7 @@ ide_devset_get(io_32bit, io_32bit); ...@@ -254,7 +254,7 @@ ide_devset_get(io_32bit, io_32bit);
static int set_io_32bit(ide_drive_t *drive, int arg) static int set_io_32bit(ide_drive_t *drive, int arg)
{ {
if (drive->no_io_32bit) if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
return -EPERM; return -EPERM;
if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
...@@ -265,19 +265,22 @@ static int set_io_32bit(ide_drive_t *drive, int arg) ...@@ -265,19 +265,22 @@ static int set_io_32bit(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(ksettings, keep_settings); ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
static int set_ksettings(ide_drive_t *drive, int arg) static int set_ksettings(ide_drive_t *drive, int arg)
{ {
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
return -EINVAL; return -EINVAL;
drive->keep_settings = arg; if (arg)
drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
else
drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
return 0; return 0;
} }
ide_devset_get(using_dma, using_dma); ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
static int set_using_dma(ide_drive_t *drive, int arg) static int set_using_dma(ide_drive_t *drive, int arg)
{ {
...@@ -339,17 +342,20 @@ static int set_pio_mode(ide_drive_t *drive, int arg) ...@@ -339,17 +342,20 @@ static int set_pio_mode(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(unmaskirq, unmask); ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
static int set_unmaskirq(ide_drive_t *drive, int arg) static int set_unmaskirq(ide_drive_t *drive, int arg)
{ {
if (drive->no_unmask) if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
return -EPERM; return -EPERM;
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
return -EINVAL; return -EINVAL;
drive->unmask = arg; if (arg)
drive->dev_flags |= IDE_DFLAG_UNMASK;
else
drive->dev_flags &= ~IDE_DFLAG_UNMASK;
return 0; return 0;
} }
...@@ -713,16 +719,16 @@ static void ide_dev_apply_params(ide_drive_t *drive) ...@@ -713,16 +719,16 @@ static void ide_dev_apply_params(ide_drive_t *drive)
if (ide_nodma & (1 << i)) { if (ide_nodma & (1 << i)) {
printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name); printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name);
drive->nodma = 1; drive->dev_flags |= IDE_DFLAG_NODMA;
} }
if (ide_noflush & (1 << i)) { if (ide_noflush & (1 << i)) {
printk(KERN_INFO "ide: disabling flush requests for %s\n", printk(KERN_INFO "ide: disabling flush requests for %s\n",
drive->name); drive->name);
drive->noflush = 1; drive->dev_flags |= IDE_DFLAG_NOFLUSH;
} }
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->noprobe = 1; drive->dev_flags |= IDE_DFLAG_NOPROBE;
} }
if (ide_nowerr & (1 << i)) { if (ide_nowerr & (1 << i)) {
printk(KERN_INFO "ide: ignoring the ATA_DF bit for %s\n", printk(KERN_INFO "ide: ignoring the ATA_DF bit for %s\n",
...@@ -731,7 +737,7 @@ static void ide_dev_apply_params(ide_drive_t *drive) ...@@ -731,7 +737,7 @@ static void ide_dev_apply_params(ide_drive_t *drive)
} }
if (ide_cdroms & (1 << i)) { if (ide_cdroms & (1 << i)) {
printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name); printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name);
drive->present = 1; drive->dev_flags |= IDE_DFLAG_PRESENT;
drive->media = ide_cdrom; drive->media = ide_cdrom;
/* an ATAPI device ignores DRDY */ /* an ATAPI device ignores DRDY */
drive->ready_stat = 0; drive->ready_stat = 0;
...@@ -740,11 +746,12 @@ static void ide_dev_apply_params(ide_drive_t *drive) ...@@ -740,11 +746,12 @@ static void ide_dev_apply_params(ide_drive_t *drive)
drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl; drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl;
drive->head = drive->bios_head = ide_disks_chs[i].head; drive->head = drive->bios_head = ide_disks_chs[i].head;
drive->sect = drive->bios_sect = ide_disks_chs[i].sect; drive->sect = drive->bios_sect = ide_disks_chs[i].sect;
drive->forced_geom = 1;
printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n", printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n",
drive->name, drive->name,
drive->cyl, drive->head, drive->sect); drive->cyl, drive->head, drive->sect);
drive->present = 1;
drive->dev_flags |= IDE_DFLAG_FORCED_GEOM | IDE_DFLAG_PRESENT;
drive->media = ide_disk; drive->media = ide_disk;
drive->ready_stat = ATA_DRDY; drive->ready_stat = ATA_DRDY;
} }
......
...@@ -120,7 +120,8 @@ static void ht6560b_selectproc (ide_drive_t *drive) ...@@ -120,7 +120,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
* Need to enforce prefetch sometimes because otherwise * Need to enforce prefetch sometimes because otherwise
* it'll hang (hard). * it'll hang (hard).
*/ */
if (drive->media != ide_disk || !drive->present) if (drive->media != ide_disk ||
(drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
select |= HT_PREFETCH_MODE; select |= HT_PREFETCH_MODE;
if (select != current_select || timing != current_timing) { if (select != current_select || timing != current_timing) {
...@@ -249,11 +250,11 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state) ...@@ -249,11 +250,11 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
*/ */
if (state) { if (state) {
drive->drive_data |= t; /* enable prefetch mode */ drive->drive_data |= t; /* enable prefetch mode */
drive->no_unmask = 1; drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
drive->unmask = 0; drive->dev_flags &= ~IDE_DFLAG_UNMASK;
} else { } else {
drive->drive_data &= ~t; /* disable prefetch mode */ drive->drive_data &= ~t; /* disable prefetch mode */
drive->no_unmask = 0; drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK;
} }
spin_unlock_irqrestore(&ht6560b_lock, flags); spin_unlock_irqrestore(&ht6560b_lock, flags);
......
...@@ -92,7 +92,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) ...@@ -92,7 +92,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_compute(drive, speed, &t, T, UT); ide_timing_compute(drive, speed, &t, T, UT);
if (peer->present) { if (peer->dev_flags & IDE_DFLAG_PRESENT) {
ide_timing_compute(peer, peer->current_speed, &p, T, UT); ide_timing_compute(peer, peer->current_speed, &p, T, UT);
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
} }
......
...@@ -378,13 +378,13 @@ static void __set_prefetch_mode(ide_drive_t *drive, int mode) ...@@ -378,13 +378,13 @@ static void __set_prefetch_mode(ide_drive_t *drive, int mode)
{ {
if (mode) { /* want prefetch on? */ if (mode) { /* want prefetch on? */
#if CMD640_PREFETCH_MASKS #if CMD640_PREFETCH_MASKS
drive->no_unmask = 1; drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
drive->unmask = 0; drive->dev_flags &= ~IDE_DFLAG_UNMASK;
#endif #endif
drive->no_io_32bit = 0; drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
} else { } else {
drive->no_unmask = 0; drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK;
drive->no_io_32bit = 1; drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
drive->io_32bit = 0; drive->io_32bit = 0;
} }
} }
...@@ -471,7 +471,7 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index) ...@@ -471,7 +471,7 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index)
ide_drive_t *peer = &hwif->drives[!drive->select.b.unit]; ide_drive_t *peer = &hwif->drives[!drive->select.b.unit];
unsigned int mate = index ^ 1; unsigned int mate = index ^ 1;
if (peer->present) { if (peer->dev_flags & IDE_DFLAG_PRESENT) {
if (setup_count < setup_counts[mate]) if (setup_count < setup_counts[mate])
setup_count = setup_counts[mate]; setup_count = setup_counts[mate];
if (active_count < active_counts[mate]) if (active_count < active_counts[mate])
...@@ -626,7 +626,7 @@ static void cmd640_init_dev(ide_drive_t *drive) ...@@ -626,7 +626,7 @@ static void cmd640_init_dev(ide_drive_t *drive)
*/ */
check_prefetch(drive, i); check_prefetch(drive, i);
printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n", printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n",
i, drive->no_io_32bit ? "off" : "on"); i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on");
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
} }
......
...@@ -454,7 +454,7 @@ static void it821x_quirkproc(ide_drive_t *drive) ...@@ -454,7 +454,7 @@ static void it821x_quirkproc(ide_drive_t *drive)
* IRQ mask as we may well be in PIO (eg rev 0x10) * IRQ mask as we may well be in PIO (eg rev 0x10)
* for now and we know unmasking is safe on this chipset. * for now and we know unmasking is safe on this chipset.
*/ */
drive->unmask = 1; drive->dev_flags |= IDE_DFLAG_UNMASK;
} else { } else {
/* /*
* Perform fixups on smart mode. We need to "lose" some * Perform fixups on smart mode. We need to "lose" some
......
...@@ -137,7 +137,7 @@ static void __devinit superio_init_iops(struct hwif_s *hwif) ...@@ -137,7 +137,7 @@ static void __devinit superio_init_iops(struct hwif_s *hwif)
static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
/* /*
* This routine either enables/disables (according to drive->present) * This routine either enables/disables (according to IDE_DFLAG_PRESENT)
* the IRQ associated with the port (HWIF(drive)), * the IRQ associated with the port (HWIF(drive)),
* and selects either PIO or DMA handshaking for the next I/O operation. * and selects either PIO or DMA handshaking for the next I/O operation.
*/ */
...@@ -153,7 +153,11 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) ...@@ -153,7 +153,11 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
/* Adjust IRQ enable bit */ /* Adjust IRQ enable bit */
bit = 1 << (8 + hwif->channel); bit = 1 << (8 + hwif->channel);
new = drive->present ? (new & ~bit) : (new | bit);
if (drive->dev_flags & IDE_DFLAG_PRESENT)
new &= ~bit;
else
new |= bit;
/* Select PIO or DMA, DMA may only be selected for one drive/channel. */ /* Select PIO or DMA, DMA may only be selected for one drive/channel. */
bit = 1 << (20 + drive->select.b.unit + (hwif->channel << 1)); bit = 1 << (20 + drive->select.b.unit + (hwif->channel << 1));
...@@ -187,7 +191,8 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) ...@@ -187,7 +191,8 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
static void ns87415_selectproc (ide_drive_t *drive) static void ns87415_selectproc (ide_drive_t *drive)
{ {
ns87415_prepare_drive (drive, drive->using_dma); ns87415_prepare_drive(drive,
!!(drive->dev_flags & IDE_DFLAG_USING_DMA));
} }
static int ns87415_dma_end(ide_drive_t *drive) static int ns87415_dma_end(ide_drive_t *drive)
......
...@@ -168,7 +168,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) ...@@ -168,7 +168,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive)
{ {
if (drive->current_speed > XFER_UDMA_2) if (drive->current_speed > XFER_UDMA_2)
pdc_old_enable_66MHz_clock(drive->hwif); pdc_old_enable_66MHz_clock(drive->hwif);
if (drive->media != ide_disk || drive->addressing == 1) { if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) {
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
unsigned long high_16 = hwif->extra_base - 16; unsigned long high_16 = hwif->extra_base - 16;
...@@ -188,7 +188,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) ...@@ -188,7 +188,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive)
static int pdc202xx_dma_end(ide_drive_t *drive) static int pdc202xx_dma_end(ide_drive_t *drive)
{ {
if (drive->media != ide_disk || drive->addressing == 1) { if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
unsigned long high_16 = hwif->extra_base - 16; unsigned long high_16 = hwif->extra_base - 16;
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
......
...@@ -216,7 +216,8 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -216,7 +216,8 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
if (mode != -1) { if (mode != -1) {
printk("SC1200: %s: changing (U)DMA mode\n", drive->name); printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
ide_dma_off_quietly(drive); ide_dma_off_quietly(drive);
if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma) if (ide_set_dma_mode(drive, mode) == 0 &&
(drive->dev_flags & IDE_DFLAG_USING_DMA))
hwif->dma_ops->dma_host_set(drive, 1); hwif->dma_ops->dma_host_set(drive, 1);
return; return;
} }
......
...@@ -161,7 +161,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) ...@@ -161,7 +161,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
} }
/* enable IRQ if not probing */ /* enable IRQ if not probing */
if (drive->present) { if (drive->dev_flags & IDE_DFLAG_PRESENT) {
reg = inw(hwif->config_data + 3); reg = inw(hwif->config_data + 3);
reg &= 0x13; reg &= 0x13;
reg &= ~(1 << hwif->channel); reg &= ~(1 << hwif->channel);
...@@ -173,7 +173,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) ...@@ -173,7 +173,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
static void trm290_selectproc (ide_drive_t *drive) static void trm290_selectproc (ide_drive_t *drive)
{ {
trm290_prepare_drive(drive, drive->using_dma); trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
} }
static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
......
...@@ -966,11 +966,11 @@ static void pmac_ide_init_dev(ide_drive_t *drive) ...@@ -966,11 +966,11 @@ static void pmac_ide_init_dev(ide_drive_t *drive)
if (pmif->mediabay) { if (pmif->mediabay) {
#ifdef CONFIG_PMAC_MEDIABAY #ifdef CONFIG_PMAC_MEDIABAY
if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) { if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) {
drive->noprobe = 0; drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
return; return;
} }
#endif #endif
drive->noprobe = 1; drive->dev_flags |= IDE_DFLAG_NOPROBE;
} }
} }
......
...@@ -331,7 +331,8 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r ...@@ -331,7 +331,8 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
if (blk_sense_request(rq) || blk_special_request(rq)) { if (blk_sense_request(rq) || blk_special_request(rq)) {
struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
if (drive->using_dma && !idescsi_map_sg(drive, pc)) if ((drive->dev_flags & IDE_DFLAG_USING_DMA) &&
idescsi_map_sg(drive, pc) == 0)
pc->flags |= PC_FLAG_DMA_OK; pc->flags |= PC_FLAG_DMA_OK;
return idescsi_issue_pc(drive, pc); return idescsi_issue_pc(drive, pc);
...@@ -415,7 +416,7 @@ static void ide_scsi_remove(ide_drive_t *drive) ...@@ -415,7 +416,7 @@ static void ide_scsi_remove(ide_drive_t *drive)
ide_scsi_put(scsi); ide_scsi_put(scsi);
drive->scsi = 0; drive->dev_flags &= ~IDE_DFLAG_SCSI;
} }
static int ide_scsi_probe(ide_drive_t *); static int ide_scsi_probe(ide_drive_t *);
...@@ -767,7 +768,7 @@ static int ide_scsi_probe(ide_drive_t *drive) ...@@ -767,7 +768,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
!(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
return -ENODEV; return -ENODEV;
drive->scsi = 1; drive->dev_flags |= IDE_DFLAG_SCSI;
g = alloc_disk(1 << PARTN_BITS); g = alloc_disk(1 << PARTN_BITS);
if (!g) if (!g)
...@@ -808,7 +809,7 @@ static int ide_scsi_probe(ide_drive_t *drive) ...@@ -808,7 +809,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
put_disk(g); put_disk(g);
out_host_put: out_host_put:
drive->scsi = 0; drive->dev_flags &= ~IDE_DFLAG_SCSI;
scsi_host_put(host); scsi_host_put(host);
return err; return err;
} }
......
...@@ -459,6 +459,55 @@ enum { ...@@ -459,6 +459,55 @@ enum {
IDE_AFLAG_NO_AUTOCLOSE = (1 << 29), IDE_AFLAG_NO_AUTOCLOSE = (1 << 29),
}; };
/* device flags */
enum {
/* restore settings after device reset */
IDE_DFLAG_KEEP_SETTINGS = (1 << 0),
/* device is using DMA for read/write */
IDE_DFLAG_USING_DMA = (1 << 1),
/* okay to unmask other IRQs */
IDE_DFLAG_UNMASK = (1 << 2),
/* don't attempt flushes */
IDE_DFLAG_NOFLUSH = (1 << 3),
/* DSC overlap */
IDE_DFLAG_DSC_OVERLAP = (1 << 4),
/* give potential excess bandwidth */
IDE_DFLAG_NICE1 = (1 << 5),
/* device is physically present */
IDE_DFLAG_PRESENT = (1 << 6),
/* device ejected hint */
IDE_DFLAG_DEAD = (1 << 7),
/* id read from device (synthetic if not set) */
IDE_DFLAG_ID_READ = (1 << 8),
IDE_DFLAG_NOPROBE = (1 << 9),
/* need to do check_media_change() */
IDE_DFLAG_REMOVABLE = (1 << 10),
/* needed for removable devices */
IDE_DFLAG_ATTACH = (1 << 11),
IDE_DFLAG_FORCED_GEOM = (1 << 12),
/* disallow setting unmask bit */
IDE_DFLAG_NO_UNMASK = (1 << 13),
/* disallow enabling 32-bit I/O */
IDE_DFLAG_NO_IO_32BIT = (1 << 14),
/* for removable only: door lock/unlock works */
IDE_DFLAG_DOORLOCKING = (1 << 15),
/* disallow DMA */
IDE_DFLAG_NODMA = (1 << 16),
/* powermanagment told us not to do anything, so sleep nicely */
IDE_DFLAG_BLOCKED = (1 << 17),
/* ide-scsi emulation */
IDE_DFLAG_SCSI = (1 << 18),
/* sleeping & sleep field valid */
IDE_DFLAG_SLEEPING = (1 << 19),
IDE_DFLAG_POST_RESET = (1 << 20),
IDE_DFLAG_UDMA33_WARNED = (1 << 21),
IDE_DFLAG_LBA48 = (1 << 22),
/* status of write cache */
IDE_DFLAG_WCACHE = (1 << 23),
/* used for ignoring ATA_DF */
IDE_DFLAG_NOWERR = (1 << 24),
};
struct ide_drive_s { struct ide_drive_s {
char name[4]; /* drive name, such as "hda" */ char name[4]; /* drive name, such as "hda" */
char driver_req[10]; /* requests specific driver */ char driver_req[10]; /* requests specific driver */
...@@ -475,6 +524,8 @@ struct ide_drive_s { ...@@ -475,6 +524,8 @@ struct ide_drive_s {
#endif #endif
struct hwif_s *hwif; /* actually (ide_hwif_t *) */ struct hwif_s *hwif; /* actually (ide_hwif_t *) */
unsigned long dev_flags;
unsigned long sleep; /* sleep until this time */ unsigned long sleep; /* sleep until this time */
unsigned long service_start; /* time we started last request */ unsigned long service_start; /* time we started last request */
unsigned long service_time; /* service time of last request */ unsigned long service_time; /* service time of last request */
...@@ -487,32 +538,6 @@ struct ide_drive_s { ...@@ -487,32 +538,6 @@ struct ide_drive_s {
u8 state; /* retry state */ u8 state; /* retry state */
u8 waiting_for_dma; /* dma currently in progress */ u8 waiting_for_dma; /* dma currently in progress */
unsigned keep_settings : 1; /* restore settings after drive reset */
unsigned using_dma : 1; /* disk is using dma for read/write */
unsigned unmask : 1; /* okay to unmask other irqs */
unsigned noflush : 1; /* don't attempt flushes */
unsigned dsc_overlap : 1; /* DSC overlap */
unsigned nice1 : 1; /* give potential excess bandwidth */
unsigned present : 1; /* drive is physically present */
unsigned dead : 1; /* device ejected hint */
unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */
unsigned noprobe : 1; /* from: hdx=noprobe */
unsigned removable : 1; /* 1 if need to do check_media_change */
unsigned attach : 1; /* needed for removable devices */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
unsigned no_unmask : 1; /* disallow setting unmask bit */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
unsigned doorlocking : 1; /* for removable only: door lock/unlock works */
unsigned nodma : 1; /* disallow DMA */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */
unsigned sleeping : 1; /* 1=sleeping & sleep field valid */
unsigned post_reset : 1;
unsigned udma33_warned : 1;
unsigned addressing : 1; /* 0=28-bit, 1=48-bit */
unsigned wcache : 1; /* status of write cache */
unsigned nowerr : 1; /* used for ignoring ATA_DF */
u8 quirk_list; /* considered quirky, set for a specific host */ u8 quirk_list; /* considered quirky, set for a specific host */
u8 init_speed; /* transfer rate set at boot */ u8 init_speed; /* transfer rate set at boot */
u8 current_speed; /* current transfer rate set */ u8 current_speed; /* current transfer rate set */
...@@ -826,6 +851,22 @@ static int set_##name(ide_drive_t *drive, int arg) \ ...@@ -826,6 +851,22 @@ static int set_##name(ide_drive_t *drive, int arg) \
return 0; \ return 0; \
} }
#define ide_devset_get_flag(name, flag) \
static int get_##name(ide_drive_t *drive) \
{ \
return !!(drive->dev_flags & flag); \
}
#define ide_devset_set_flag(name, flag) \
static int set_##name(ide_drive_t *drive, int arg) \
{ \
if (arg) \
drive->dev_flags |= flag; \
else \
drive->dev_flags &= ~flag; \
return 0; \
}
#define __IDE_DEVSET(_name, _flags, _get, _set) \ #define __IDE_DEVSET(_name, _flags, _get, _set) \
const struct ide_devset ide_devset_##_name = \ const struct ide_devset ide_devset_##_name = \
__DEVSET(_flags, _get, _set) __DEVSET(_flags, _get, _set)
...@@ -861,6 +902,11 @@ ide_devset_get(_name, _field); \ ...@@ -861,6 +902,11 @@ ide_devset_get(_name, _field); \
ide_devset_set(_name, _field); \ ide_devset_set(_name, _field); \
IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
#define ide_devset_rw_flag(_name, _field) \
ide_devset_get_flag(_name, _field); \
ide_devset_set_flag(_name, _field); \
IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
struct ide_proc_devset { struct ide_proc_devset {
const char *name; const char *name;
const struct ide_devset *setting; const struct ide_devset *setting;
...@@ -1587,6 +1633,6 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive) ...@@ -1587,6 +1633,6 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive)
{ {
ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1]; ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1];
return peer->present ? peer : NULL; return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL;
} }
#endif /* _IDE_H */ #endif /* _IDE_H */
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