forked from luck/tmp_suning_uos_patched
The big changes for IPMI that just went in had a few problems. These
have been in for-next for a while, each since about their creation date. I forgot the bugzilla reference on the second one (ipmi_si: Fix oops with PCI devices) so I rebased to add that. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJaLo1KAAoJEGHzjJCRm/+B0HsP/joYHLSzoAESfihnx9JD1dn6 JM8ZV8fu7e1ZpnrxyGj/dPLSBS1k8wsVKAEGrL5ETz4UOuwIR6/61wpzfyrQf/L5 0ZBhpv8dAxpHvFZGGE1NCF4jNlo20K0i8YQk9lUxB3Nml3udUd+GUA/Li5d2vGo4 e6xZyS15euNmHwnELaCguS9Vz79xusLmFvgicmi5l7+Y3X4Ul/sNL+pGySYUMqxU NvsH3fTDXJfRv2FCnJwn1sUGpPPPH0uYhaLKXNpekt0PgNNTlTzFWGnfRJrbD/+q OWXrfuqiwoCSRhfOXooI2vGAIZ+jjL/vBS9827EGjf0tWgTVnOx+wuDND15uZkxP LizUG0ZPcov0veDh1mExIBIU2sCGkZ+dlQeGLaVBQ4tNgbyJyWi5HiwvFc5r9s/e /ak0kkt9J54T4MgtEMBEEHSMatUixM8eXJ7K9ySZANP5vXlLmcpXVKBHEB42QWBN I1V5o1PVHxV8IrG/zOiWYBLYraWocEaNat/LzlbqGMfoVyb1gXpAI8Cbjphq1xOU 49J5oY6L8MHNIu0VkEV9MtIEyLAM/V/nd8WQ3YpD/4UJnVoWcorBQWSC7NssWFm8 5N4dq7kXSnUM4yA21PMogFCnRToO6nrK/ijxOkzWmPbDnvDDywQY/bnj7dAKFQri iQ67umU2z0+U4juY+Lls =3M4K -----END PGP SIGNATURE----- Merge tag 'for-linus-4.15-2' of git://github.com/cminyard/linux-ipmi Pull IPMI fixes from Corey Minyard. * tag 'for-linus-4.15-2' of git://github.com/cminyard/linux-ipmi: ipmi_si: fix crash on parisc ipmi_si: Fix oops with PCI devices ipmi: Stop timers before cleaning up the module
This commit is contained in:
commit
bfb529ee79
|
@ -199,6 +199,9 @@ struct smi_info {
|
|||
/* The timer for this si. */
|
||||
struct timer_list si_timer;
|
||||
|
||||
/* This flag is set, if the timer can be set */
|
||||
bool timer_can_start;
|
||||
|
||||
/* This flag is set, if the timer is running (timer_pending() isn't enough) */
|
||||
bool timer_running;
|
||||
|
||||
|
@ -355,6 +358,8 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
|
|||
|
||||
static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
|
||||
{
|
||||
if (!smi_info->timer_can_start)
|
||||
return;
|
||||
smi_info->last_timeout_jiffies = jiffies;
|
||||
mod_timer(&smi_info->si_timer, new_val);
|
||||
smi_info->timer_running = true;
|
||||
|
@ -374,21 +379,18 @@ static void start_new_msg(struct smi_info *smi_info, unsigned char *msg,
|
|||
smi_info->handlers->start_transaction(smi_info->si_sm, msg, size);
|
||||
}
|
||||
|
||||
static void start_check_enables(struct smi_info *smi_info, bool start_timer)
|
||||
static void start_check_enables(struct smi_info *smi_info)
|
||||
{
|
||||
unsigned char msg[2];
|
||||
|
||||
msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
|
||||
msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
|
||||
|
||||
if (start_timer)
|
||||
start_new_msg(smi_info, msg, 2);
|
||||
else
|
||||
smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
|
||||
start_new_msg(smi_info, msg, 2);
|
||||
smi_info->si_state = SI_CHECKING_ENABLES;
|
||||
}
|
||||
|
||||
static void start_clear_flags(struct smi_info *smi_info, bool start_timer)
|
||||
static void start_clear_flags(struct smi_info *smi_info)
|
||||
{
|
||||
unsigned char msg[3];
|
||||
|
||||
|
@ -397,10 +399,7 @@ static void start_clear_flags(struct smi_info *smi_info, bool start_timer)
|
|||
msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
|
||||
msg[2] = WDT_PRE_TIMEOUT_INT;
|
||||
|
||||
if (start_timer)
|
||||
start_new_msg(smi_info, msg, 3);
|
||||
else
|
||||
smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
|
||||
start_new_msg(smi_info, msg, 3);
|
||||
smi_info->si_state = SI_CLEARING_FLAGS;
|
||||
}
|
||||
|
||||
|
@ -435,11 +434,11 @@ static void start_getting_events(struct smi_info *smi_info)
|
|||
* Note that we cannot just use disable_irq(), since the interrupt may
|
||||
* be shared.
|
||||
*/
|
||||
static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer)
|
||||
static inline bool disable_si_irq(struct smi_info *smi_info)
|
||||
{
|
||||
if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) {
|
||||
smi_info->interrupt_disabled = true;
|
||||
start_check_enables(smi_info, start_timer);
|
||||
start_check_enables(smi_info);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -449,7 +448,7 @@ static inline bool enable_si_irq(struct smi_info *smi_info)
|
|||
{
|
||||
if ((smi_info->io.irq) && (smi_info->interrupt_disabled)) {
|
||||
smi_info->interrupt_disabled = false;
|
||||
start_check_enables(smi_info, true);
|
||||
start_check_enables(smi_info);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -467,7 +466,7 @@ static struct ipmi_smi_msg *alloc_msg_handle_irq(struct smi_info *smi_info)
|
|||
|
||||
msg = ipmi_alloc_smi_msg();
|
||||
if (!msg) {
|
||||
if (!disable_si_irq(smi_info, true))
|
||||
if (!disable_si_irq(smi_info))
|
||||
smi_info->si_state = SI_NORMAL;
|
||||
} else if (enable_si_irq(smi_info)) {
|
||||
ipmi_free_smi_msg(msg);
|
||||
|
@ -483,7 +482,7 @@ static void handle_flags(struct smi_info *smi_info)
|
|||
/* Watchdog pre-timeout */
|
||||
smi_inc_stat(smi_info, watchdog_pretimeouts);
|
||||
|
||||
start_clear_flags(smi_info, true);
|
||||
start_clear_flags(smi_info);
|
||||
smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
|
||||
if (smi_info->intf)
|
||||
ipmi_smi_watchdog_pretimeout(smi_info->intf);
|
||||
|
@ -866,7 +865,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
|
|||
* disable and messages disabled.
|
||||
*/
|
||||
if (smi_info->supports_event_msg_buff || smi_info->io.irq) {
|
||||
start_check_enables(smi_info, true);
|
||||
start_check_enables(smi_info);
|
||||
} else {
|
||||
smi_info->curr_msg = alloc_msg_handle_irq(smi_info);
|
||||
if (!smi_info->curr_msg)
|
||||
|
@ -1167,6 +1166,7 @@ static int smi_start_processing(void *send_info,
|
|||
|
||||
/* Set up the timer that drives the interface. */
|
||||
timer_setup(&new_smi->si_timer, smi_timeout, 0);
|
||||
new_smi->timer_can_start = true;
|
||||
smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
|
||||
|
||||
/* Try to claim any interrupts. */
|
||||
|
@ -1936,10 +1936,12 @@ static void check_for_broken_irqs(struct smi_info *smi_info)
|
|||
check_set_rcv_irq(smi_info);
|
||||
}
|
||||
|
||||
static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
|
||||
static inline void stop_timer_and_thread(struct smi_info *smi_info)
|
||||
{
|
||||
if (smi_info->thread != NULL)
|
||||
kthread_stop(smi_info->thread);
|
||||
|
||||
smi_info->timer_can_start = false;
|
||||
if (smi_info->timer_running)
|
||||
del_timer_sync(&smi_info->si_timer);
|
||||
}
|
||||
|
@ -2152,7 +2154,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
* Start clearing the flags before we enable interrupts or the
|
||||
* timer to avoid racing with the timer.
|
||||
*/
|
||||
start_clear_flags(new_smi, false);
|
||||
start_clear_flags(new_smi);
|
||||
|
||||
/*
|
||||
* IRQ is defined to be set when non-zero. req_events will
|
||||
|
@ -2238,7 +2240,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
dev_set_drvdata(new_smi->io.dev, NULL);
|
||||
|
||||
out_err_stop_timer:
|
||||
wait_for_timer_and_thread(new_smi);
|
||||
stop_timer_and_thread(new_smi);
|
||||
|
||||
out_err:
|
||||
new_smi->interrupt_disabled = true;
|
||||
|
@ -2388,7 +2390,7 @@ static void cleanup_one_si(struct smi_info *to_clean)
|
|||
*/
|
||||
if (to_clean->io.irq_cleanup)
|
||||
to_clean->io.irq_cleanup(&to_clean->io);
|
||||
wait_for_timer_and_thread(to_clean);
|
||||
stop_timer_and_thread(to_clean);
|
||||
|
||||
/*
|
||||
* Timeouts are stopped, now make sure the interrupts are off
|
||||
|
@ -2400,7 +2402,7 @@ static void cleanup_one_si(struct smi_info *to_clean)
|
|||
schedule_timeout_uninterruptible(1);
|
||||
}
|
||||
if (to_clean->handlers)
|
||||
disable_si_irq(to_clean, false);
|
||||
disable_si_irq(to_clean);
|
||||
while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
|
||||
poll(to_clean);
|
||||
schedule_timeout_uninterruptible(1);
|
||||
|
|
|
@ -10,6 +10,8 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev)
|
|||
{
|
||||
struct si_sm_io io;
|
||||
|
||||
memset(&io, 0, sizeof(io));
|
||||
|
||||
io.si_type = SI_KCS;
|
||||
io.addr_source = SI_DEVICETREE;
|
||||
io.addr_type = IPMI_MEM_ADDR_SPACE;
|
||||
|
|
|
@ -103,10 +103,13 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
|
|||
io.addr_source_cleanup = ipmi_pci_cleanup;
|
||||
io.addr_source_data = pdev;
|
||||
|
||||
if (pci_resource_flags(pdev, 0) & IORESOURCE_IO)
|
||||
if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
|
||||
io.addr_type = IPMI_IO_ADDR_SPACE;
|
||||
else
|
||||
io.io_setup = ipmi_si_port_setup;
|
||||
} else {
|
||||
io.addr_type = IPMI_MEM_ADDR_SPACE;
|
||||
io.io_setup = ipmi_si_mem_setup;
|
||||
}
|
||||
io.addr_data = pci_resource_start(pdev, 0);
|
||||
|
||||
io.regspacing = ipmi_pci_probe_regspacing(&io);
|
||||
|
|
Loading…
Reference in New Issue
Block a user