提交 6c82a8af 编写于 作者: C Cornelia Huck 提交者: Martin Schwidefsky

[S390] qeth: New read configuration data.

Instead of the deprecated read_conf_data(), implement a new function
qeth_read_conf_data().
Signed-off-by: NCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 17283b56
...@@ -288,6 +288,7 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) ...@@ -288,6 +288,7 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
*/ */
#define IF_NAME_LEN 16 #define IF_NAME_LEN 16
#define QETH_TX_TIMEOUT 100 * HZ #define QETH_TX_TIMEOUT 100 * HZ
#define QETH_RCD_TIMEOUT 60 * HZ
#define QETH_HEADER_SIZE 32 #define QETH_HEADER_SIZE 32
#define MAX_PORTNO 15 #define MAX_PORTNO 15
#define QETH_FAKE_LL_LEN_ETH ETH_HLEN #define QETH_FAKE_LL_LEN_ETH ETH_HLEN
...@@ -582,6 +583,8 @@ enum qeth_channel_states { ...@@ -582,6 +583,8 @@ enum qeth_channel_states {
CH_STATE_ACTIVATING, CH_STATE_ACTIVATING,
CH_STATE_HALTED, CH_STATE_HALTED,
CH_STATE_STOPPED, CH_STATE_STOPPED,
CH_STATE_RCD,
CH_STATE_RCD_DONE,
}; };
/** /**
* card state machine * card state machine
......
...@@ -315,7 +315,8 @@ qeth_alloc_card(void) ...@@ -315,7 +315,8 @@ qeth_alloc_card(void)
} }
static long static long
__qeth_check_irb_error(struct ccw_device *cdev, struct irb *irb) __qeth_check_irb_error(struct ccw_device *cdev, unsigned long intparm,
struct irb *irb)
{ {
if (!IS_ERR(irb)) if (!IS_ERR(irb))
return 0; return 0;
...@@ -330,6 +331,14 @@ __qeth_check_irb_error(struct ccw_device *cdev, struct irb *irb) ...@@ -330,6 +331,14 @@ __qeth_check_irb_error(struct ccw_device *cdev, struct irb *irb)
PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id); PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id);
QETH_DBF_TEXT(trace, 2, "ckirberr"); QETH_DBF_TEXT(trace, 2, "ckirberr");
QETH_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT); QETH_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT);
if (intparm == QETH_RCD_PARM) {
struct qeth_card *card = CARD_FROM_CDEV(cdev);
if (card && (card->data.ccwdev == cdev)) {
card->data.state = CH_STATE_DOWN;
wake_up(&card->wait_q);
}
}
break; break;
default: default:
PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb), PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
...@@ -401,7 +410,7 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -401,7 +410,7 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
QETH_DBF_TEXT(trace,5,"irq"); QETH_DBF_TEXT(trace,5,"irq");
if (__qeth_check_irb_error(cdev, irb)) if (__qeth_check_irb_error(cdev, intparm, irb))
return; return;
cstat = irb->scsw.cstat; cstat = irb->scsw.cstat;
dstat = irb->scsw.dstat; dstat = irb->scsw.dstat;
...@@ -429,7 +438,8 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -429,7 +438,8 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
channel->state = CH_STATE_HALTED; channel->state = CH_STATE_HALTED;
/*let's wake up immediately on data channel*/ /*let's wake up immediately on data channel*/
if ((channel == &card->data) && (intparm != 0)) if ((channel == &card->data) && (intparm != 0) &&
(intparm != QETH_RCD_PARM))
goto out; goto out;
if (intparm == QETH_CLEAR_CHANNEL_PARM) { if (intparm == QETH_CLEAR_CHANNEL_PARM) {
...@@ -453,6 +463,10 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -453,6 +463,10 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
HEXDUMP16(WARN,"irb: ",irb); HEXDUMP16(WARN,"irb: ",irb);
HEXDUMP16(WARN,"sense data: ",irb->ecw); HEXDUMP16(WARN,"sense data: ",irb->ecw);
} }
if (intparm == QETH_RCD_PARM) {
channel->state = CH_STATE_DOWN;
goto out;
}
rc = qeth_get_problem(cdev,irb); rc = qeth_get_problem(cdev,irb);
if (rc) { if (rc) {
qeth_schedule_recovery(card); qeth_schedule_recovery(card);
...@@ -460,6 +474,10 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -460,6 +474,10 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
} }
} }
if (intparm == QETH_RCD_PARM) {
channel->state = CH_STATE_RCD_DONE;
goto out;
}
if (intparm) { if (intparm) {
buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm); buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
buffer->state = BUF_STATE_PROCESSED; buffer->state = BUF_STATE_PROCESSED;
...@@ -1204,6 +1222,54 @@ qeth_probe_device(struct ccwgroup_device *gdev) ...@@ -1204,6 +1222,54 @@ qeth_probe_device(struct ccwgroup_device *gdev)
} }
static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
int *length)
{
struct ciw *ciw;
char *rcd_buf;
int ret;
struct qeth_channel *channel = &card->data;
unsigned long flags;
/*
* scan for RCD command in extended SenseID data
*/
ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD);
if (!ciw || ciw->cmd == 0)
return -EOPNOTSUPP;
rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
if (!rcd_buf)
return -ENOMEM;
channel->ccw.cmd_code = ciw->cmd;
channel->ccw.cda = (__u32) __pa (rcd_buf);
channel->ccw.count = ciw->count;
channel->ccw.flags = CCW_FLAG_SLI;
channel->state = CH_STATE_RCD;
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
ret = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
QETH_RCD_PARM, LPM_ANYPATH, 0,
QETH_RCD_TIMEOUT);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (!ret)
wait_event(card->wait_q,
(channel->state == CH_STATE_RCD_DONE ||
channel->state == CH_STATE_DOWN));
if (channel->state == CH_STATE_DOWN)
ret = -EIO;
else
channel->state = CH_STATE_DOWN;
if (ret) {
kfree(rcd_buf);
*buffer = NULL;
*length = 0;
} else {
*length = ciw->count;
*buffer = rcd_buf;
}
return ret;
}
static int static int
qeth_get_unitaddr(struct qeth_card *card) qeth_get_unitaddr(struct qeth_card *card)
{ {
...@@ -1212,9 +1278,9 @@ qeth_get_unitaddr(struct qeth_card *card) ...@@ -1212,9 +1278,9 @@ qeth_get_unitaddr(struct qeth_card *card)
int rc; int rc;
QETH_DBF_TEXT(setup, 2, "getunit"); QETH_DBF_TEXT(setup, 2, "getunit");
rc = read_conf_data(CARD_DDEV(card), (void **) &prcd, &length); rc = qeth_read_conf_data(card, (void **) &prcd, &length);
if (rc) { if (rc) {
PRINT_ERR("read_conf_data for device %s returned %i\n", PRINT_ERR("qeth_read_conf_data for device %s returned %i\n",
CARD_DDEV_ID(card), rc); CARD_DDEV_ID(card), rc);
return rc; return rc;
} }
...@@ -1223,6 +1289,7 @@ qeth_get_unitaddr(struct qeth_card *card) ...@@ -1223,6 +1289,7 @@ qeth_get_unitaddr(struct qeth_card *card)
card->info.cula = prcd[63]; card->info.cula = prcd[63];
card->info.guestlan = ((prcd[0x10] == _ascebc['V']) && card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
(prcd[0x11] == _ascebc['M'])); (prcd[0x11] == _ascebc['M']));
kfree(prcd);
return 0; return 0;
} }
......
...@@ -37,6 +37,7 @@ extern unsigned char IPA_PDU_HEADER[]; ...@@ -37,6 +37,7 @@ extern unsigned char IPA_PDU_HEADER[];
#define QETH_CLEAR_CHANNEL_PARM -10 #define QETH_CLEAR_CHANNEL_PARM -10
#define QETH_HALT_CHANNEL_PARM -11 #define QETH_HALT_CHANNEL_PARM -11
#define QETH_RCD_PARM -12
/*****************************************************************************/ /*****************************************************************************/
/* IP Assist related definitions */ /* IP Assist related definitions */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册