static ssize_t qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct qeth_card *card = dev_get_drvdata(dev); char *tmp; int i, rc = 0; enum qeth_discipline_id newdis; if (!card) return -EINVAL; mutex_lock(&card->discipline_mutex); if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } i = simple_strtoul(buf, &tmp, 16); switch (i) { case 0: newdis = QETH_DISCIPLINE_LAYER3; break; case 1: newdis = QETH_DISCIPLINE_LAYER2; break; default: rc = -EINVAL; goto out; } if (card->options.layer2 == newdis) goto out; else { card->info.mac_bits = 0; if (card->discipline) { card->discipline->remove(card->gdev); qeth_core_free_discipline(card); } } rc = qeth_core_load_discipline(card, newdis); if (rc) goto out; rc = card->discipline->setup(card->gdev); out: mutex_unlock(&card->discipline_mutex); return rc ? rc : count; }
static ssize_t qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct qeth_card *card = dev_get_drvdata(dev); struct net_device *ndev; char *tmp; int i, rc = 0; enum qeth_discipline_id newdis; if (!card) return -EINVAL; mutex_lock(&card->discipline_mutex); if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; } i = simple_strtoul(buf, &tmp, 16); switch (i) { case 0: newdis = QETH_DISCIPLINE_LAYER3; break; case 1: newdis = QETH_DISCIPLINE_LAYER2; break; default: rc = -EINVAL; goto out; } if (card->options.layer == newdis) goto out; if (card->info.layer_enforced) { /* fixed layer, can't switch */ rc = -EOPNOTSUPP; goto out; } if (card->discipline) { /* start with a new, pristine netdevice: */ ndev = qeth_clone_netdev(card->dev); if (!ndev) { rc = -ENOMEM; goto out; } card->discipline->remove(card->gdev); qeth_core_free_discipline(card); free_netdev(card->dev); card->dev = ndev; } rc = qeth_core_load_discipline(card, newdis); if (rc) goto out; rc = card->discipline->setup(card->gdev); if (rc) qeth_core_free_discipline(card); out: mutex_unlock(&card->discipline_mutex); return rc ? rc : count; }