|
@@ -53,7 +53,7 @@ struct kmem_cache *qeth_core_header_cache;
|
|
|
EXPORT_SYMBOL_GPL(qeth_core_header_cache);
|
|
|
|
|
|
static struct device *qeth_core_root_dev;
|
|
|
-static unsigned int known_devices[][10] = QETH_MODELLIST_ARRAY;
|
|
|
+static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY;
|
|
|
static struct lock_class_key qdio_out_skb_queue_key;
|
|
|
|
|
|
static void qeth_send_control_data_cb(struct qeth_channel *,
|
|
@@ -111,21 +111,29 @@ static inline const char *qeth_get_cardname(struct qeth_card *card)
|
|
|
{
|
|
|
if (card->info.guestlan) {
|
|
|
switch (card->info.type) {
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
return " Guest LAN QDIO";
|
|
|
case QETH_CARD_TYPE_IQD:
|
|
|
return " Guest LAN Hiper";
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ return " Guest LAN QDIO - OSM";
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
+ return " Guest LAN QDIO - OSX";
|
|
|
default:
|
|
|
return " unknown";
|
|
|
}
|
|
|
} else {
|
|
|
switch (card->info.type) {
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
return " OSD Express";
|
|
|
case QETH_CARD_TYPE_IQD:
|
|
|
return " HiperSockets";
|
|
|
case QETH_CARD_TYPE_OSN:
|
|
|
return " OSN QDIO";
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ return " OSM QDIO";
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
+ return " OSX QDIO";
|
|
|
default:
|
|
|
return " unknown";
|
|
|
}
|
|
@@ -138,16 +146,20 @@ const char *qeth_get_cardname_short(struct qeth_card *card)
|
|
|
{
|
|
|
if (card->info.guestlan) {
|
|
|
switch (card->info.type) {
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
return "GuestLAN QDIO";
|
|
|
case QETH_CARD_TYPE_IQD:
|
|
|
return "GuestLAN Hiper";
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ return "GuestLAN OSM";
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
+ return "GuestLAN OSX";
|
|
|
default:
|
|
|
return "unknown";
|
|
|
}
|
|
|
} else {
|
|
|
switch (card->info.type) {
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
switch (card->info.link_type) {
|
|
|
case QETH_LINK_TYPE_FAST_ETH:
|
|
|
return "OSD_100";
|
|
@@ -172,6 +184,10 @@ const char *qeth_get_cardname_short(struct qeth_card *card)
|
|
|
return "HiperSockets";
|
|
|
case QETH_CARD_TYPE_OSN:
|
|
|
return "OSN";
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ return "OSM_1000";
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
+ return "OSX_10GIG";
|
|
|
default:
|
|
|
return "unknown";
|
|
|
}
|
|
@@ -419,7 +435,8 @@ void qeth_clear_ipacmd_list(struct qeth_card *card)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
|
|
|
|
|
|
-static int qeth_check_idx_response(unsigned char *buffer)
|
|
|
+static int qeth_check_idx_response(struct qeth_card *card,
|
|
|
+ unsigned char *buffer)
|
|
|
{
|
|
|
if (!buffer)
|
|
|
return 0;
|
|
@@ -434,6 +451,12 @@ static int qeth_check_idx_response(unsigned char *buffer)
|
|
|
QETH_DBF_TEXT(TRACE, 2, "ckidxres");
|
|
|
QETH_DBF_TEXT(TRACE, 2, " idxterm");
|
|
|
QETH_DBF_TEXT_(TRACE, 2, " rc%d", -EIO);
|
|
|
+ if (buffer[4] == 0xf6) {
|
|
|
+ dev_err(&card->gdev->dev,
|
|
|
+ "The qeth device is not configured "
|
|
|
+ "for the OSI layer required by z/VM\n");
|
|
|
+ return -EPERM;
|
|
|
+ }
|
|
|
return -EIO;
|
|
|
}
|
|
|
return 0;
|
|
@@ -528,18 +551,19 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel,
|
|
|
struct qeth_ipa_cmd *cmd;
|
|
|
unsigned long flags;
|
|
|
int keep_reply;
|
|
|
+ int rc = 0;
|
|
|
|
|
|
QETH_DBF_TEXT(TRACE, 4, "sndctlcb");
|
|
|
|
|
|
card = CARD_FROM_CDEV(channel->ccwdev);
|
|
|
- if (qeth_check_idx_response(iob->data)) {
|
|
|
+ rc = qeth_check_idx_response(card, iob->data);
|
|
|
+ switch (rc) {
|
|
|
+ case 0:
|
|
|
+ break;
|
|
|
+ case -EIO:
|
|
|
qeth_clear_ipacmd_list(card);
|
|
|
- if (((iob->data[2] & 0xc0) == 0xc0) && iob->data[4] == 0xf6)
|
|
|
- dev_err(&card->gdev->dev,
|
|
|
- "The qeth device is not configured "
|
|
|
- "for the OSI layer required by z/VM\n");
|
|
|
- else
|
|
|
- qeth_schedule_recovery(card);
|
|
|
+ qeth_schedule_recovery(card);
|
|
|
+ default:
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -719,7 +743,7 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
|
|
|
QETH_DBF_TEXT(TRACE, 2, "CGENCHK");
|
|
|
dev_warn(&cdev->dev, "The qeth device driver "
|
|
|
"failed to recover an error on the device\n");
|
|
|
- QETH_DBF_MESSAGE(2, "%s check on device dstat=x%x, cstat=x%x ",
|
|
|
+ QETH_DBF_MESSAGE(2, "%s check on device dstat=x%x, cstat=x%x\n",
|
|
|
dev_name(&cdev->dev), dstat, cstat);
|
|
|
print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET,
|
|
|
16, 1, irb, 64, 1);
|
|
@@ -998,9 +1022,8 @@ static void qeth_clean_channel(struct qeth_channel *channel)
|
|
|
kfree(channel->iob[cnt].data);
|
|
|
}
|
|
|
|
|
|
-static int qeth_is_1920_device(struct qeth_card *card)
|
|
|
+static void qeth_get_channel_path_desc(struct qeth_card *card)
|
|
|
{
|
|
|
- int single_queue = 0;
|
|
|
struct ccw_device *ccwdev;
|
|
|
struct channelPath_dsc {
|
|
|
u8 flags;
|
|
@@ -1013,17 +1036,25 @@ static int qeth_is_1920_device(struct qeth_card *card)
|
|
|
u8 chpp;
|
|
|
} *chp_dsc;
|
|
|
|
|
|
- QETH_DBF_TEXT(SETUP, 2, "chk_1920");
|
|
|
+ QETH_DBF_TEXT(SETUP, 2, "chp_desc");
|
|
|
|
|
|
ccwdev = card->data.ccwdev;
|
|
|
chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0);
|
|
|
if (chp_dsc != NULL) {
|
|
|
/* CHPP field bit 6 == 1 -> single queue */
|
|
|
- single_queue = ((chp_dsc->chpp & 0x02) == 0x02);
|
|
|
+ if ((chp_dsc->chpp & 0x02) == 0x02)
|
|
|
+ card->qdio.no_out_queues = 1;
|
|
|
+ card->info.func_level = 0x4100 + chp_dsc->desc;
|
|
|
kfree(chp_dsc);
|
|
|
}
|
|
|
- QETH_DBF_TEXT_(SETUP, 2, "rc:%x", single_queue);
|
|
|
- return single_queue;
|
|
|
+ if (card->qdio.no_out_queues == 1) {
|
|
|
+ card->qdio.default_out_queue = 0;
|
|
|
+ dev_info(&card->gdev->dev,
|
|
|
+ "Priority Queueing not supported\n");
|
|
|
+ }
|
|
|
+ QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues);
|
|
|
+ QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
static void qeth_init_qdio_info(struct qeth_card *card)
|
|
@@ -1171,18 +1202,17 @@ static int qeth_determine_card_type(struct qeth_card *card)
|
|
|
|
|
|
card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
|
|
|
card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
|
|
|
- while (known_devices[i][4]) {
|
|
|
- if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
|
|
|
- (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
|
|
|
- card->info.type = known_devices[i][4];
|
|
|
- card->qdio.no_out_queues = known_devices[i][8];
|
|
|
- card->info.is_multicast_different = known_devices[i][9];
|
|
|
- if (qeth_is_1920_device(card)) {
|
|
|
- dev_info(&card->gdev->dev,
|
|
|
- "Priority Queueing not supported\n");
|
|
|
- card->qdio.no_out_queues = 1;
|
|
|
- card->qdio.default_out_queue = 0;
|
|
|
- }
|
|
|
+ while (known_devices[i][QETH_DEV_MODEL_IND]) {
|
|
|
+ if ((CARD_RDEV(card)->id.dev_type ==
|
|
|
+ known_devices[i][QETH_DEV_TYPE_IND]) &&
|
|
|
+ (CARD_RDEV(card)->id.dev_model ==
|
|
|
+ known_devices[i][QETH_DEV_MODEL_IND])) {
|
|
|
+ card->info.type = known_devices[i][QETH_DEV_MODEL_IND];
|
|
|
+ card->qdio.no_out_queues =
|
|
|
+ known_devices[i][QETH_QUEUE_NO_IND];
|
|
|
+ card->info.is_multicast_different =
|
|
|
+ known_devices[i][QETH_MULTICAST_IND];
|
|
|
+ qeth_get_channel_path_desc(card);
|
|
|
return 0;
|
|
|
}
|
|
|
i++;
|
|
@@ -1399,22 +1429,20 @@ static void qeth_init_tokens(struct qeth_card *card)
|
|
|
|
|
|
static void qeth_init_func_level(struct qeth_card *card)
|
|
|
{
|
|
|
- if (card->ipato.enabled) {
|
|
|
- if (card->info.type == QETH_CARD_TYPE_IQD)
|
|
|
- card->info.func_level =
|
|
|
- QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT;
|
|
|
- else
|
|
|
- card->info.func_level =
|
|
|
- QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
|
|
|
- } else {
|
|
|
- if (card->info.type == QETH_CARD_TYPE_IQD)
|
|
|
- /*FIXME:why do we have same values for dis and ena for
|
|
|
- osae??? */
|
|
|
+ switch (card->info.type) {
|
|
|
+ case QETH_CARD_TYPE_IQD:
|
|
|
+ if (card->ipato.enabled)
|
|
|
card->info.func_level =
|
|
|
- QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
|
|
|
+ QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT;
|
|
|
else
|
|
|
card->info.func_level =
|
|
|
- QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT;
|
|
|
+ QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
|
|
|
+ break;
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
+ card->info.func_level = QETH_IDX_FUNC_LEVEL_OSD;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1561,7 +1589,7 @@ static void qeth_idx_write_cb(struct qeth_channel *channel,
|
|
|
card = CARD_FROM_CDEV(channel->ccwdev);
|
|
|
|
|
|
if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
|
|
|
- if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
|
|
|
+ if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == QETH_IDX_ACT_ERR_EXCL)
|
|
|
dev_err(&card->write.ccwdev->dev,
|
|
|
"The adapter is used exclusively by another "
|
|
|
"host\n");
|
|
@@ -1597,27 +1625,35 @@ static void qeth_idx_read_cb(struct qeth_channel *channel,
|
|
|
}
|
|
|
|
|
|
card = CARD_FROM_CDEV(channel->ccwdev);
|
|
|
- if (qeth_check_idx_response(iob->data))
|
|
|
+ if (qeth_check_idx_response(card, iob->data))
|
|
|
goto out;
|
|
|
|
|
|
if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
|
|
|
- if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
|
|
|
+ switch (QETH_IDX_ACT_CAUSE_CODE(iob->data)) {
|
|
|
+ case QETH_IDX_ACT_ERR_EXCL:
|
|
|
dev_err(&card->write.ccwdev->dev,
|
|
|
"The adapter is used exclusively by another "
|
|
|
"host\n");
|
|
|
- else
|
|
|
+ break;
|
|
|
+ case QETH_IDX_ACT_ERR_AUTH:
|
|
|
+ dev_err(&card->read.ccwdev->dev,
|
|
|
+ "Setting the device online failed because of "
|
|
|
+ "insufficient LPAR authorization\n");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on read channel:"
|
|
|
" negative reply\n",
|
|
|
dev_name(&card->read.ccwdev->dev));
|
|
|
+ }
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * temporary fix for microcode bug
|
|
|
- * to revert it,replace OR by AND
|
|
|
- */
|
|
|
+ * * temporary fix for microcode bug
|
|
|
+ * * to revert it,replace OR by AND
|
|
|
+ * */
|
|
|
if ((!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) ||
|
|
|
- (card->info.type == QETH_CARD_TYPE_OSAE))
|
|
|
+ (card->info.type == QETH_CARD_TYPE_OSD))
|
|
|
card->info.portname_required = 1;
|
|
|
|
|
|
memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
|
|
@@ -1826,7 +1862,7 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card)
|
|
|
return 1500;
|
|
|
case QETH_CARD_TYPE_IQD:
|
|
|
return card->info.max_mtu;
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
switch (card->info.link_type) {
|
|
|
case QETH_LINK_TYPE_HSTR:
|
|
|
case QETH_LINK_TYPE_LANE_TR:
|
|
@@ -1834,6 +1870,9 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card)
|
|
|
default:
|
|
|
return 1492;
|
|
|
}
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
+ return 1492;
|
|
|
default:
|
|
|
return 1500;
|
|
|
}
|
|
@@ -1844,8 +1883,10 @@ static inline int qeth_get_max_mtu_for_card(int cardtype)
|
|
|
switch (cardtype) {
|
|
|
|
|
|
case QETH_CARD_TYPE_UNKNOWN:
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
case QETH_CARD_TYPE_OSN:
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
return 61440;
|
|
|
case QETH_CARD_TYPE_IQD:
|
|
|
return 57344;
|
|
@@ -1883,7 +1924,9 @@ static inline int qeth_get_mtu_outof_framesize(int framesize)
|
|
|
static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu)
|
|
|
{
|
|
|
switch (card->info.type) {
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
return ((mtu >= 576) && (mtu <= 61440));
|
|
|
case QETH_CARD_TYPE_IQD:
|
|
|
return ((mtu >= 576) &&
|
|
@@ -1934,6 +1977,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
|
|
|
card->info.link_type = link_type;
|
|
|
} else
|
|
|
card->info.link_type = 0;
|
|
|
+ QETH_DBF_TEXT_(SETUP, 2, "link%d", link_type);
|
|
|
QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc);
|
|
|
return 0;
|
|
|
}
|
|
@@ -2246,7 +2290,9 @@ static void qeth_print_status_no_portname(struct qeth_card *card)
|
|
|
void qeth_print_status_message(struct qeth_card *card)
|
|
|
{
|
|
|
switch (card->info.type) {
|
|
|
- case QETH_CARD_TYPE_OSAE:
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
/* VM will use a non-zero first character
|
|
|
* to indicate a HiperSockets like reporting
|
|
|
* of the level OSA sets the first character to zero
|
|
@@ -2553,9 +2599,11 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card,
|
|
|
QETH_DBF_TEXT(TRACE, 3, "quyadpcb");
|
|
|
|
|
|
cmd = (struct qeth_ipa_cmd *) data;
|
|
|
- if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f)
|
|
|
+ if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) {
|
|
|
card->info.link_type =
|
|
|
cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
|
|
|
+ QETH_DBF_TEXT_(SETUP, 2, "lnk %d", card->info.link_type);
|
|
|
+ }
|
|
|
card->options.adp.supported_funcs =
|
|
|
cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
|
|
|
return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
|
|
@@ -2945,7 +2993,8 @@ EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
|
|
|
int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
|
|
|
int ipv, int cast_type)
|
|
|
{
|
|
|
- if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE))
|
|
|
+ if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD ||
|
|
|
+ card->info.type == QETH_CARD_TYPE_OSX))
|
|
|
return card->qdio.default_out_queue;
|
|
|
switch (card->qdio.no_out_queues) {
|
|
|
case 4:
|
|
@@ -3507,13 +3556,14 @@ int qeth_set_access_ctrl_online(struct qeth_card *card)
|
|
|
|
|
|
QETH_DBF_TEXT(TRACE, 4, "setactlo");
|
|
|
|
|
|
- if (card->info.type == QETH_CARD_TYPE_OSAE &&
|
|
|
- qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
|
|
|
+ if ((card->info.type == QETH_CARD_TYPE_OSD ||
|
|
|
+ card->info.type == QETH_CARD_TYPE_OSX) &&
|
|
|
+ qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
|
|
|
rc = qeth_setadpparms_set_access_ctrl(card,
|
|
|
card->options.isolation);
|
|
|
if (rc) {
|
|
|
QETH_DBF_MESSAGE(3,
|
|
|
- "IPA(SET_ACCESS_CTRL,%s,%d) sent failed",
|
|
|
+ "IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n",
|
|
|
card->gdev->dev.kobj.name,
|
|
|
rc);
|
|
|
}
|
|
@@ -3845,9 +3895,16 @@ static void qeth_core_free_card(struct qeth_card *card)
|
|
|
}
|
|
|
|
|
|
static struct ccw_device_id qeth_ids[] = {
|
|
|
- {CCW_DEVICE(0x1731, 0x01), .driver_info = QETH_CARD_TYPE_OSAE},
|
|
|
- {CCW_DEVICE(0x1731, 0x05), .driver_info = QETH_CARD_TYPE_IQD},
|
|
|
- {CCW_DEVICE(0x1731, 0x06), .driver_info = QETH_CARD_TYPE_OSN},
|
|
|
+ {CCW_DEVICE_DEVTYPE(0x1731, 0x01, 0x1732, 0x01),
|
|
|
+ .driver_info = QETH_CARD_TYPE_OSD},
|
|
|
+ {CCW_DEVICE_DEVTYPE(0x1731, 0x05, 0x1732, 0x05),
|
|
|
+ .driver_info = QETH_CARD_TYPE_IQD},
|
|
|
+ {CCW_DEVICE_DEVTYPE(0x1731, 0x06, 0x1732, 0x06),
|
|
|
+ .driver_info = QETH_CARD_TYPE_OSN},
|
|
|
+ {CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x03),
|
|
|
+ .driver_info = QETH_CARD_TYPE_OSM},
|
|
|
+ {CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x02),
|
|
|
+ .driver_info = QETH_CARD_TYPE_OSX},
|
|
|
{},
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(ccw, qeth_ids);
|
|
@@ -4251,25 +4308,25 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
|
|
|
goto err_card;
|
|
|
}
|
|
|
|
|
|
- if (card->info.type == QETH_CARD_TYPE_OSN) {
|
|
|
+ if (card->info.type == QETH_CARD_TYPE_OSN)
|
|
|
rc = qeth_core_create_osn_attributes(dev);
|
|
|
- if (rc)
|
|
|
- goto err_card;
|
|
|
+ else
|
|
|
+ rc = qeth_core_create_device_attributes(dev);
|
|
|
+ if (rc)
|
|
|
+ goto err_card;
|
|
|
+ switch (card->info.type) {
|
|
|
+ case QETH_CARD_TYPE_OSN:
|
|
|
+ case QETH_CARD_TYPE_OSM:
|
|
|
rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
|
|
|
- if (rc) {
|
|
|
- qeth_core_remove_osn_attributes(dev);
|
|
|
- goto err_card;
|
|
|
- }
|
|
|
+ if (rc)
|
|
|
+ goto err_attr;
|
|
|
rc = card->discipline.ccwgdriver->probe(card->gdev);
|
|
|
- if (rc) {
|
|
|
- qeth_core_free_discipline(card);
|
|
|
- qeth_core_remove_osn_attributes(dev);
|
|
|
- goto err_card;
|
|
|
- }
|
|
|
- } else {
|
|
|
- rc = qeth_core_create_device_attributes(dev);
|
|
|
if (rc)
|
|
|
- goto err_card;
|
|
|
+ goto err_disc;
|
|
|
+ case QETH_CARD_TYPE_OSD:
|
|
|
+ case QETH_CARD_TYPE_OSX:
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
|
|
@@ -4279,6 +4336,13 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
|
|
|
qeth_determine_capabilities(card);
|
|
|
return 0;
|
|
|
|
|
|
+err_disc:
|
|
|
+ qeth_core_free_discipline(card);
|
|
|
+err_attr:
|
|
|
+ if (card->info.type == QETH_CARD_TYPE_OSN)
|
|
|
+ qeth_core_remove_osn_attributes(dev);
|
|
|
+ else
|
|
|
+ qeth_core_remove_device_attributes(dev);
|
|
|
err_card:
|
|
|
qeth_core_free_card(card);
|
|
|
err_dev:
|