ide: use lock bitops for ports serialization (v2)

* Add ->host_busy field to struct ide_host and use it's first bit
  together with lock bitops to provide new ports serialization method.

* Convert core IDE code to use new ide_[un]lock_host() helpers.

  This removes the need for taking hwgroup->lock if host is already
  busy on serialized hosts and makes it possible to merge ide_hwgroup_t
  into ide_hwif_t (done in the later patch).

* Remove no longer needed ide_hwgroup_t.busy and ide_[un]lock_hwgroup().

* Update do_ide_request() documentation.

v2:
* ide_release_lock() should be called inside IDE_HFLAG_SERIALIZE check.

* Add ide_hwif_t.busy flag and ide_[un]lock_port() for serializing
  devices on a port.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
Bartlomiej Zolnierkiewicz 2009-01-06 17:20:49 +01:00
parent efe0397eef
commit 5b31f855f1
2 changed files with 69 additions and 71 deletions

View file

@ -828,6 +828,7 @@ typedef struct hwif_s {
unsigned present : 1; /* this interface exists */
unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
unsigned busy : 1; /* serializes devices on a port */
struct device gendev;
struct device *portdev;
@ -851,8 +852,13 @@ struct ide_host {
unsigned long host_flags;
void *host_priv;
ide_hwif_t *cur_port; /* for hosts requiring serialization */
/* used for hosts requiring serialization */
volatile long host_busy;
};
#define IDE_HOST_BUSY 0
/*
* internal ide interrupt handler type
*/
@ -866,8 +872,6 @@ typedef struct hwgroup_s {
/* irq handler, if active */
ide_startstop_t (*handler)(ide_drive_t *);
/* BOOL: protects all fields below */
volatile int busy;
/* BOOL: polling active & poll_timeout field valid */
unsigned int polling : 1;
@ -1271,26 +1275,6 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id);
static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup, ide_hwif_t *hwif)
{
if (hwgroup->busy)
return 1;
hwgroup->busy = 1;
/* for atari only */
ide_get_lock(ide_intr, hwif);
return 0;
}
static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
{
/* for atari only */
ide_release_lock();
hwgroup->busy = 0;
}
extern void do_ide_request(struct request_queue *);
void ide_init_disk(struct gendisk *, ide_drive_t *);
@ -1617,13 +1601,6 @@ static inline void ide_set_max_pio(ide_drive_t *drive)
extern spinlock_t ide_lock;
extern struct mutex ide_cfg_mtx;
/*
* Structure locking:
*
* ide_hwgroup_t->busy: hwgroup->lock
* ide_hwif_t->{hwgroup,mate}: constant, no locking
* ide_drive_t->hwif: constant, no locking
*/
#define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)