floppy: don't use PREPARE_[DELAYED_]WORK
PREPARE_[DELAYED_]WORK() are being phased out. They have few users and a nasty surprise in terms of reentrancy guarantee as workqueue considers work items to be different if they don't have the same work function. floppy has been multiplexing floppy_work and fd_timer with multiple work functions. Introduce floppy_work_workfn() and fd_timer_workfn() which invoke floppy_work_fn and fd_timer_fn respectively and always use the two functions as the work functions and update the users to set floppy_work_fn and fd_timer_fn instead of overriding work functions using PREPARE_[DELAYED_]WORK(). It would probably be best to route this with other related updates through the workqueue tree. Lightly tested using qemu. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
4a8bb7f548
commit
75ddb38f09
@ -961,17 +961,31 @@ static void empty(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLARE_WORK(floppy_work, NULL);
|
static void (*floppy_work_fn)(void);
|
||||||
|
|
||||||
|
static void floppy_work_workfn(struct work_struct *work)
|
||||||
|
{
|
||||||
|
floppy_work_fn();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLARE_WORK(floppy_work, floppy_work_workfn);
|
||||||
|
|
||||||
static void schedule_bh(void (*handler)(void))
|
static void schedule_bh(void (*handler)(void))
|
||||||
{
|
{
|
||||||
WARN_ON(work_pending(&floppy_work));
|
WARN_ON(work_pending(&floppy_work));
|
||||||
|
|
||||||
PREPARE_WORK(&floppy_work, (work_func_t)handler);
|
floppy_work_fn = handler;
|
||||||
queue_work(floppy_wq, &floppy_work);
|
queue_work(floppy_wq, &floppy_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLARE_DELAYED_WORK(fd_timer, NULL);
|
static void (*fd_timer_fn)(void) = NULL;
|
||||||
|
|
||||||
|
static void fd_timer_workfn(struct work_struct *work)
|
||||||
|
{
|
||||||
|
fd_timer_fn();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLARE_DELAYED_WORK(fd_timer, fd_timer_workfn);
|
||||||
|
|
||||||
static void cancel_activity(void)
|
static void cancel_activity(void)
|
||||||
{
|
{
|
||||||
@ -982,7 +996,7 @@ static void cancel_activity(void)
|
|||||||
|
|
||||||
/* this function makes sure that the disk stays in the drive during the
|
/* this function makes sure that the disk stays in the drive during the
|
||||||
* transfer */
|
* transfer */
|
||||||
static void fd_watchdog(struct work_struct *arg)
|
static void fd_watchdog(void)
|
||||||
{
|
{
|
||||||
debug_dcl(DP->flags, "calling disk change from watchdog\n");
|
debug_dcl(DP->flags, "calling disk change from watchdog\n");
|
||||||
|
|
||||||
@ -993,7 +1007,7 @@ static void fd_watchdog(struct work_struct *arg)
|
|||||||
reset_fdc();
|
reset_fdc();
|
||||||
} else {
|
} else {
|
||||||
cancel_delayed_work(&fd_timer);
|
cancel_delayed_work(&fd_timer);
|
||||||
PREPARE_DELAYED_WORK(&fd_timer, fd_watchdog);
|
fd_timer_fn = fd_watchdog;
|
||||||
queue_delayed_work(floppy_wq, &fd_timer, HZ / 10);
|
queue_delayed_work(floppy_wq, &fd_timer, HZ / 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1005,7 +1019,8 @@ static void main_command_interrupt(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* waits for a delay (spinup or select) to pass */
|
/* waits for a delay (spinup or select) to pass */
|
||||||
static int fd_wait_for_completion(unsigned long expires, work_func_t function)
|
static int fd_wait_for_completion(unsigned long expires,
|
||||||
|
void (*function)(void))
|
||||||
{
|
{
|
||||||
if (FDCS->reset) {
|
if (FDCS->reset) {
|
||||||
reset_fdc(); /* do the reset during sleep to win time
|
reset_fdc(); /* do the reset during sleep to win time
|
||||||
@ -1016,7 +1031,7 @@ static int fd_wait_for_completion(unsigned long expires, work_func_t function)
|
|||||||
|
|
||||||
if (time_before(jiffies, expires)) {
|
if (time_before(jiffies, expires)) {
|
||||||
cancel_delayed_work(&fd_timer);
|
cancel_delayed_work(&fd_timer);
|
||||||
PREPARE_DELAYED_WORK(&fd_timer, function);
|
fd_timer_fn = function;
|
||||||
queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies);
|
queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1334,8 +1349,7 @@ static int fdc_dtr(void)
|
|||||||
* Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
|
* Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
|
||||||
*/
|
*/
|
||||||
FDCS->dtr = raw_cmd->rate & 3;
|
FDCS->dtr = raw_cmd->rate & 3;
|
||||||
return fd_wait_for_completion(jiffies + 2UL * HZ / 100,
|
return fd_wait_for_completion(jiffies + 2UL * HZ / 100, floppy_ready);
|
||||||
(work_func_t)floppy_ready);
|
|
||||||
} /* fdc_dtr */
|
} /* fdc_dtr */
|
||||||
|
|
||||||
static void tell_sector(void)
|
static void tell_sector(void)
|
||||||
@ -1440,7 +1454,7 @@ static void setup_rw_floppy(void)
|
|||||||
int flags;
|
int flags;
|
||||||
int dflags;
|
int dflags;
|
||||||
unsigned long ready_date;
|
unsigned long ready_date;
|
||||||
work_func_t function;
|
void (*function)(void);
|
||||||
|
|
||||||
flags = raw_cmd->flags;
|
flags = raw_cmd->flags;
|
||||||
if (flags & (FD_RAW_READ | FD_RAW_WRITE))
|
if (flags & (FD_RAW_READ | FD_RAW_WRITE))
|
||||||
@ -1454,9 +1468,9 @@ static void setup_rw_floppy(void)
|
|||||||
*/
|
*/
|
||||||
if (time_after(ready_date, jiffies + DP->select_delay)) {
|
if (time_after(ready_date, jiffies + DP->select_delay)) {
|
||||||
ready_date -= DP->select_delay;
|
ready_date -= DP->select_delay;
|
||||||
function = (work_func_t)floppy_start;
|
function = floppy_start;
|
||||||
} else
|
} else
|
||||||
function = (work_func_t)setup_rw_floppy;
|
function = setup_rw_floppy;
|
||||||
|
|
||||||
/* wait until the floppy is spinning fast enough */
|
/* wait until the floppy is spinning fast enough */
|
||||||
if (fd_wait_for_completion(ready_date, function))
|
if (fd_wait_for_completion(ready_date, function))
|
||||||
@ -1486,7 +1500,7 @@ static void setup_rw_floppy(void)
|
|||||||
inr = result();
|
inr = result();
|
||||||
cont->interrupt();
|
cont->interrupt();
|
||||||
} else if (flags & FD_RAW_NEED_DISK)
|
} else if (flags & FD_RAW_NEED_DISK)
|
||||||
fd_watchdog(NULL);
|
fd_watchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int blind_seek;
|
static int blind_seek;
|
||||||
@ -1863,7 +1877,7 @@ static int start_motor(void (*function)(void))
|
|||||||
|
|
||||||
/* wait_for_completion also schedules reset if needed. */
|
/* wait_for_completion also schedules reset if needed. */
|
||||||
return fd_wait_for_completion(DRS->select_date + DP->select_delay,
|
return fd_wait_for_completion(DRS->select_date + DP->select_delay,
|
||||||
(work_func_t)function);
|
function);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void floppy_ready(void)
|
static void floppy_ready(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user