aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r--drivers/ide/ide.c81
1 files changed, 15 insertions, 66 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 349d7fa75585..9dcf5aed92cb 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -250,42 +250,9 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
250 250
251DEFINE_MUTEX(ide_setting_mtx); 251DEFINE_MUTEX(ide_setting_mtx);
252 252
253/**
254 * ide_spin_wait_hwgroup - wait for group
255 * @drive: drive in the group
256 *
257 * Wait for an IDE device group to go non busy and then return
258 * holding the ide_lock which guards the hwgroup->busy status
259 * and right to use it.
260 */
261
262int ide_spin_wait_hwgroup (ide_drive_t *drive)
263{
264 ide_hwgroup_t *hwgroup = HWGROUP(drive);
265 unsigned long timeout = jiffies + (3 * HZ);
266
267 spin_lock_irq(&ide_lock);
268
269 while (hwgroup->busy) {
270 unsigned long lflags;
271 spin_unlock_irq(&ide_lock);
272 local_irq_set(lflags);
273 if (time_after(jiffies, timeout)) {
274 local_irq_restore(lflags);
275 printk(KERN_ERR "%s: channel busy\n", drive->name);
276 return -EBUSY;
277 }
278 local_irq_restore(lflags);
279 spin_lock_irq(&ide_lock);
280 }
281 return 0;
282}
283
284EXPORT_SYMBOL(ide_spin_wait_hwgroup);
285
286ide_devset_get(io_32bit, io_32bit); 253ide_devset_get(io_32bit, io_32bit);
287 254
288int set_io_32bit(ide_drive_t *drive, int arg) 255static int set_io_32bit(ide_drive_t *drive, int arg)
289{ 256{
290 if (drive->no_io_32bit) 257 if (drive->no_io_32bit)
291 return -EPERM; 258 return -EPERM;
@@ -293,37 +260,28 @@ int set_io_32bit(ide_drive_t *drive, int arg)
293 if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) 260 if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
294 return -EINVAL; 261 return -EINVAL;
295 262
296 if (ide_spin_wait_hwgroup(drive))
297 return -EBUSY;
298
299 drive->io_32bit = arg; 263 drive->io_32bit = arg;
300 264
301 spin_unlock_irq(&ide_lock);
302
303 return 0; 265 return 0;
304} 266}
305 267
306ide_devset_get(ksettings, keep_settings); 268ide_devset_get(ksettings, keep_settings);
307 269
308int set_ksettings(ide_drive_t *drive, int arg) 270static int set_ksettings(ide_drive_t *drive, int arg)
309{ 271{
310 if (arg < 0 || arg > 1) 272 if (arg < 0 || arg > 1)
311 return -EINVAL; 273 return -EINVAL;
312 274
313 if (ide_spin_wait_hwgroup(drive))
314 return -EBUSY;
315 drive->keep_settings = arg; 275 drive->keep_settings = arg;
316 spin_unlock_irq(&ide_lock);
317 276
318 return 0; 277 return 0;
319} 278}
320 279
321ide_devset_get(using_dma, using_dma); 280ide_devset_get(using_dma, using_dma);
322 281
323int set_using_dma(ide_drive_t *drive, int arg) 282static int set_using_dma(ide_drive_t *drive, int arg)
324{ 283{
325#ifdef CONFIG_BLK_DEV_IDEDMA 284#ifdef CONFIG_BLK_DEV_IDEDMA
326 ide_hwif_t *hwif = drive->hwif;
327 int err = -EPERM; 285 int err = -EPERM;
328 286
329 if (arg < 0 || arg > 1) 287 if (arg < 0 || arg > 1)
@@ -332,18 +290,9 @@ int set_using_dma(ide_drive_t *drive, int arg)
332 if (ata_id_has_dma(drive->id) == 0) 290 if (ata_id_has_dma(drive->id) == 0)
333 goto out; 291 goto out;
334 292
335 if (hwif->dma_ops == NULL) 293 if (drive->hwif->dma_ops == NULL)
336 goto out; 294 goto out;
337 295
338 err = -EBUSY;
339 if (ide_spin_wait_hwgroup(drive))
340 goto out;
341 /*
342 * set ->busy flag, unlock and let it ride
343 */
344 hwif->hwgroup->busy = 1;
345 spin_unlock_irq(&ide_lock);
346
347 err = 0; 296 err = 0;
348 297
349 if (arg) { 298 if (arg) {
@@ -352,12 +301,6 @@ int set_using_dma(ide_drive_t *drive, int arg)
352 } else 301 } else
353 ide_dma_off(drive); 302 ide_dma_off(drive);
354 303
355 /*
356 * lock, clear ->busy flag and unlock before leaving
357 */
358 spin_lock_irq(&ide_lock);
359 hwif->hwgroup->busy = 0;
360 spin_unlock_irq(&ide_lock);
361out: 304out:
362 return err; 305 return err;
363#else 306#else
@@ -368,7 +311,7 @@ out:
368#endif 311#endif
369} 312}
370 313
371int set_pio_mode(ide_drive_t *drive, int arg) 314static int set_pio_mode(ide_drive_t *drive, int arg)
372{ 315{
373 struct request *rq; 316 struct request *rq;
374 ide_hwif_t *hwif = drive->hwif; 317 ide_hwif_t *hwif = drive->hwif;
@@ -398,7 +341,7 @@ int set_pio_mode(ide_drive_t *drive, int arg)
398 341
399ide_devset_get(unmaskirq, unmask); 342ide_devset_get(unmaskirq, unmask);
400 343
401int set_unmaskirq(ide_drive_t *drive, int arg) 344static int set_unmaskirq(ide_drive_t *drive, int arg)
402{ 345{
403 if (drive->no_unmask) 346 if (drive->no_unmask)
404 return -EPERM; 347 return -EPERM;
@@ -406,14 +349,20 @@ int set_unmaskirq(ide_drive_t *drive, int arg)
406 if (arg < 0 || arg > 1) 349 if (arg < 0 || arg > 1)
407 return -EINVAL; 350 return -EINVAL;
408 351
409 if (ide_spin_wait_hwgroup(drive))
410 return -EBUSY;
411 drive->unmask = arg; 352 drive->unmask = arg;
412 spin_unlock_irq(&ide_lock);
413 353
414 return 0; 354 return 0;
415} 355}
416 356
357#define ide_gen_devset_rw(_name, _func) \
358__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func)
359
360ide_gen_devset_rw(io_32bit, io_32bit);
361ide_gen_devset_rw(keepsettings, ksettings);
362ide_gen_devset_rw(unmaskirq, unmaskirq);
363ide_gen_devset_rw(using_dma, using_dma);
364__IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode);
365
417static int generic_ide_suspend(struct device *dev, pm_message_t mesg) 366static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
418{ 367{
419 ide_drive_t *drive = dev->driver_data; 368 ide_drive_t *drive = dev->driver_data;