mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 02:20:52 +07:00
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: [S390] cio: online_store - trigger recognition for boxed devices [S390] cio: disallow online setting of device in transient state [S390] cio: introduce notifier for boxed state [S390] cio: introduce ccw_device_schedule_sch_unregister [S390] cio: wake up on failed recognition [S390] fix hypfs build failure [PATCH] sysrq: include interrupt.h instead of irq.h
This commit is contained in:
commit
32527bc0e4
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/gfp.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <asm/ebcdic.h>
|
#include <asm/ebcdic.h>
|
||||||
|
@ -456,6 +456,8 @@ struct ciw {
|
|||||||
#define CIO_OPER 0x0004
|
#define CIO_OPER 0x0004
|
||||||
/* Sick revalidation of device. */
|
/* Sick revalidation of device. */
|
||||||
#define CIO_REVALIDATE 0x0008
|
#define CIO_REVALIDATE 0x0008
|
||||||
|
/* Device did not respond in time. */
|
||||||
|
#define CIO_BOXED 0x0010
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct ccw_dev_id - unique identifier for ccw devices
|
* struct ccw_dev_id - unique identifier for ccw devices
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include <linux/vt_kern.h>
|
#include <linux/vt_kern.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/kexec.h>
|
#include <linux/kexec.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/hrtimer.h>
|
#include <linux/hrtimer.h>
|
||||||
#include <linux/oom.h>
|
#include <linux/oom.h>
|
||||||
|
|
||||||
|
@ -2363,6 +2363,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case CIO_GONE:
|
case CIO_GONE:
|
||||||
|
case CIO_BOXED:
|
||||||
case CIO_NO_PATH:
|
case CIO_NO_PATH:
|
||||||
/* First of all call extended error reporting. */
|
/* First of all call extended error reporting. */
|
||||||
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
|
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
|
||||||
|
@ -310,8 +310,6 @@ static void ccw_device_remove_orphan_cb(struct work_struct *work)
|
|||||||
put_device(&cdev->dev);
|
put_device(&cdev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccw_device_call_sch_unregister(struct work_struct *work);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ccw_device_remove_disconnected(struct ccw_device *cdev)
|
ccw_device_remove_disconnected(struct ccw_device *cdev)
|
||||||
{
|
{
|
||||||
@ -335,11 +333,10 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
|
|||||||
spin_unlock_irqrestore(cdev->ccwlock, flags);
|
spin_unlock_irqrestore(cdev->ccwlock, flags);
|
||||||
PREPARE_WORK(&cdev->private->kick_work,
|
PREPARE_WORK(&cdev->private->kick_work,
|
||||||
ccw_device_remove_orphan_cb);
|
ccw_device_remove_orphan_cb);
|
||||||
|
queue_work(slow_path_wq, &cdev->private->kick_work);
|
||||||
} else
|
} else
|
||||||
/* Deregister subchannel, which will kill the ccw device. */
|
/* Deregister subchannel, which will kill the ccw device. */
|
||||||
PREPARE_WORK(&cdev->private->kick_work,
|
ccw_device_schedule_sch_unregister(cdev);
|
||||||
ccw_device_call_sch_unregister);
|
|
||||||
queue_work(slow_path_wq, &cdev->private->kick_work);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -471,7 +468,7 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Do device recognition, if needed. */
|
/* Do device recognition, if needed. */
|
||||||
if (cdev->id.cu_type == 0) {
|
if (cdev->private->state == DEV_STATE_BOXED) {
|
||||||
ret = ccw_device_recognition(cdev);
|
ret = ccw_device_recognition(cdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
CIO_MSG_EVENT(0, "Couldn't start recognition "
|
CIO_MSG_EVENT(0, "Couldn't start recognition "
|
||||||
@ -482,17 +479,21 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
|
|||||||
}
|
}
|
||||||
wait_event(cdev->private->wait_q,
|
wait_event(cdev->private->wait_q,
|
||||||
cdev->private->flags.recog_done);
|
cdev->private->flags.recog_done);
|
||||||
|
if (cdev->private->state != DEV_STATE_OFFLINE)
|
||||||
|
/* recognition failed */
|
||||||
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (cdev->drv && cdev->drv->set_online)
|
if (cdev->drv && cdev->drv->set_online)
|
||||||
ccw_device_set_online(cdev);
|
ccw_device_set_online(cdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int online_store_handle_online(struct ccw_device *cdev, int force)
|
static int online_store_handle_online(struct ccw_device *cdev, int force)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = online_store_recog_and_online(cdev);
|
ret = online_store_recog_and_online(cdev);
|
||||||
if (ret)
|
if (ret && !force)
|
||||||
return ret;
|
return ret;
|
||||||
if (force && cdev->private->state == DEV_STATE_BOXED) {
|
if (force && cdev->private->state == DEV_STATE_BOXED) {
|
||||||
ret = ccw_device_stlck(cdev);
|
ret = ccw_device_stlck(cdev);
|
||||||
@ -500,7 +501,9 @@ static int online_store_handle_online(struct ccw_device *cdev, int force)
|
|||||||
return ret;
|
return ret;
|
||||||
if (cdev->id.cu_type == 0)
|
if (cdev->id.cu_type == 0)
|
||||||
cdev->private->state = DEV_STATE_NOT_OPER;
|
cdev->private->state = DEV_STATE_NOT_OPER;
|
||||||
online_store_recog_and_online(cdev);
|
ret = online_store_recog_and_online(cdev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -512,7 +515,11 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
|
|||||||
int force, ret;
|
int force, ret;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
|
||||||
if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
|
if ((cdev->private->state != DEV_STATE_OFFLINE &&
|
||||||
|
cdev->private->state != DEV_STATE_ONLINE &&
|
||||||
|
cdev->private->state != DEV_STATE_BOXED &&
|
||||||
|
cdev->private->state != DEV_STATE_DISCONNECTED) ||
|
||||||
|
atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
if (cdev->drv && !try_module_get(cdev->drv->owner)) {
|
if (cdev->drv && !try_module_get(cdev->drv->owner)) {
|
||||||
@ -1014,6 +1021,13 @@ static void ccw_device_call_sch_unregister(struct work_struct *work)
|
|||||||
put_device(&sch->dev);
|
put_device(&sch->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
|
||||||
|
{
|
||||||
|
PREPARE_WORK(&cdev->private->kick_work,
|
||||||
|
ccw_device_call_sch_unregister);
|
||||||
|
queue_work(slow_path_wq, &cdev->private->kick_work);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subchannel recognition done. Called from the state machine.
|
* subchannel recognition done. Called from the state machine.
|
||||||
*/
|
*/
|
||||||
@ -1025,19 +1039,17 @@ io_subchannel_recog_done(struct ccw_device *cdev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (cdev->private->state) {
|
switch (cdev->private->state) {
|
||||||
|
case DEV_STATE_BOXED:
|
||||||
|
/* Device did not respond in time. */
|
||||||
case DEV_STATE_NOT_OPER:
|
case DEV_STATE_NOT_OPER:
|
||||||
cdev->private->flags.recog_done = 1;
|
cdev->private->flags.recog_done = 1;
|
||||||
/* Remove device found not operational. */
|
/* Remove device found not operational. */
|
||||||
if (!get_device(&cdev->dev))
|
if (!get_device(&cdev->dev))
|
||||||
break;
|
break;
|
||||||
PREPARE_WORK(&cdev->private->kick_work,
|
ccw_device_schedule_sch_unregister(cdev);
|
||||||
ccw_device_call_sch_unregister);
|
|
||||||
queue_work(slow_path_wq, &cdev->private->kick_work);
|
|
||||||
if (atomic_dec_and_test(&ccw_device_init_count))
|
if (atomic_dec_and_test(&ccw_device_init_count))
|
||||||
wake_up(&ccw_device_init_wq);
|
wake_up(&ccw_device_init_wq);
|
||||||
break;
|
break;
|
||||||
case DEV_STATE_BOXED:
|
|
||||||
/* Device did not respond in time. */
|
|
||||||
case DEV_STATE_OFFLINE:
|
case DEV_STATE_OFFLINE:
|
||||||
/*
|
/*
|
||||||
* We can't register the device in interrupt context so
|
* We can't register the device in interrupt context so
|
||||||
@ -1551,8 +1563,7 @@ static int purge_fn(struct device *dev, void *data)
|
|||||||
goto out;
|
goto out;
|
||||||
CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
|
CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
|
||||||
priv->dev_id.devno);
|
priv->dev_id.devno);
|
||||||
PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister);
|
ccw_device_schedule_sch_unregister(cdev);
|
||||||
queue_work(slow_path_wq, &cdev->private->kick_work);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/* Abort loop in case of pending signal. */
|
/* Abort loop in case of pending signal. */
|
||||||
|
@ -87,6 +87,7 @@ int ccw_device_is_orphan(struct ccw_device *);
|
|||||||
int ccw_device_recognition(struct ccw_device *);
|
int ccw_device_recognition(struct ccw_device *);
|
||||||
int ccw_device_online(struct ccw_device *);
|
int ccw_device_online(struct ccw_device *);
|
||||||
int ccw_device_offline(struct ccw_device *);
|
int ccw_device_offline(struct ccw_device *);
|
||||||
|
void ccw_device_schedule_sch_unregister(struct ccw_device *);
|
||||||
int ccw_purge_blacklisted(void);
|
int ccw_purge_blacklisted(void);
|
||||||
|
|
||||||
/* Function prototypes for device status and basic sense stuff. */
|
/* Function prototypes for device status and basic sense stuff. */
|
||||||
|
@ -256,14 +256,13 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
|
|||||||
old_lpm = 0;
|
old_lpm = 0;
|
||||||
if (sch->lpm != old_lpm)
|
if (sch->lpm != old_lpm)
|
||||||
__recover_lost_chpids(sch, old_lpm);
|
__recover_lost_chpids(sch, old_lpm);
|
||||||
if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
|
if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
|
||||||
if (state == DEV_STATE_NOT_OPER) {
|
(state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
|
||||||
cdev->private->flags.recog_done = 1;
|
cdev->private->flags.recog_done = 1;
|
||||||
cdev->private->state = DEV_STATE_DISCONNECTED;
|
cdev->private->state = DEV_STATE_DISCONNECTED;
|
||||||
|
wake_up(&cdev->private->wait_q);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Boxed devices don't need extra treatment. */
|
|
||||||
}
|
|
||||||
notify = 0;
|
notify = 0;
|
||||||
same_dev = 0; /* Keep the compiler quiet... */
|
same_dev = 0; /* Keep the compiler quiet... */
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -274,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
|
|||||||
sch->schid.ssid, sch->schid.sch_no);
|
sch->schid.ssid, sch->schid.sch_no);
|
||||||
break;
|
break;
|
||||||
case DEV_STATE_OFFLINE:
|
case DEV_STATE_OFFLINE:
|
||||||
if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
|
if (cdev->online) {
|
||||||
same_dev = ccw_device_handle_oper(cdev);
|
same_dev = ccw_device_handle_oper(cdev);
|
||||||
notify = 1;
|
notify = 1;
|
||||||
}
|
}
|
||||||
@ -307,11 +306,16 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
|
|||||||
" subchannel 0.%x.%04x\n",
|
" subchannel 0.%x.%04x\n",
|
||||||
cdev->private->dev_id.devno,
|
cdev->private->dev_id.devno,
|
||||||
sch->schid.ssid, sch->schid.sch_no);
|
sch->schid.ssid, sch->schid.sch_no);
|
||||||
|
if (cdev->id.cu_type != 0) { /* device was recognized before */
|
||||||
|
cdev->private->flags.recog_done = 1;
|
||||||
|
cdev->private->state = DEV_STATE_BOXED;
|
||||||
|
wake_up(&cdev->private->wait_q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cdev->private->state = state;
|
cdev->private->state = state;
|
||||||
io_subchannel_recog_done(cdev);
|
io_subchannel_recog_done(cdev);
|
||||||
if (state != DEV_STATE_NOT_OPER)
|
|
||||||
wake_up(&cdev->private->wait_q);
|
wake_up(&cdev->private->wait_q);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state)
|
|||||||
|
|
||||||
cdev->private->state = state;
|
cdev->private->state = state;
|
||||||
|
|
||||||
|
if (state == DEV_STATE_BOXED) {
|
||||||
if (state == DEV_STATE_BOXED)
|
|
||||||
CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
|
CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
|
||||||
cdev->private->dev_id.devno, sch->schid.sch_no);
|
cdev->private->dev_id.devno, sch->schid.sch_no);
|
||||||
|
if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
|
||||||
|
ccw_device_schedule_sch_unregister(cdev);
|
||||||
|
cdev->private->flags.donotify = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (cdev->private->flags.donotify) {
|
if (cdev->private->flags.donotify) {
|
||||||
cdev->private->flags.donotify = 0;
|
cdev->private->flags.donotify = 0;
|
||||||
|
@ -176,6 +176,11 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
|
|||||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||||
"ccnoti4", NULL);
|
"ccnoti4", NULL);
|
||||||
break;
|
break;
|
||||||
|
case CIO_BOXED:
|
||||||
|
dev_warn(&adapter->ccw_device->dev,
|
||||||
|
"The ccw device did not respond in time.\n");
|
||||||
|
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user