diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/lcs.c | 10 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_mpc.h | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 11 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 245 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 9 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 14 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_cfdc.c | 8 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 1177 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 497 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 141 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 52 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 20 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 113 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 10 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 43 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 9 |
17 files changed, 920 insertions, 1443 deletions
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0bf70894431..09e7a053c84 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1189,7 +1189,8 @@ lcs_remove_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) spin_lock_irqsave(&card->ipm_lock, flags); list_for_each(l, &card->ipm_list) { ipm = list_entry(l, struct lcs_ipm_list, list); - for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) { + for (im4 = rcu_dereference(in4_dev->mc_list); + im4 != NULL; im4 = rcu_dereference(im4->next_rcu)) { lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); if ( (ipm->ipm.ip_addr == im4->multiaddr) && (memcmp(buf, &ipm->ipm.mac_addr, @@ -1234,7 +1235,8 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) unsigned long flags; LCS_DBF_TEXT(4, trace, "setmclst"); - for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { + for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; + im4 = rcu_dereference(im4->next_rcu)) { lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); ipm = lcs_check_addr_entry(card, im4, buf); if (ipm != NULL) @@ -1270,10 +1272,10 @@ lcs_register_mc_addresses(void *data) in4_dev = in_dev_get(card->dev); if (in4_dev == NULL) goto out; - read_lock(&in4_dev->mc_list_lock); + rcu_read_lock(); lcs_remove_mc_addresses(card,in4_dev); lcs_set_mc_addresses(card, in4_dev); - read_unlock(&in4_dev->mc_list_lock); + rcu_read_unlock(); in_dev_put(in4_dev); netif_carrier_off(card->dev); diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index e37dd8c4bf4..07d588867b5 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -333,7 +333,7 @@ struct qeth_arp_query_data { __u16 request_bits; __u16 reply_bits; __u32 no_entries; - char data; + char data; /* only for replies */ } __attribute__((packed)); /* used as parameter for arp_query reply */ diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 42fa783a70c..b5e967cf7e2 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -372,7 +372,7 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, i = simple_strtoul(buf, &tmp, 16); if ((i == 0) || (i == 1)) { if (i == card->options.performance_stats) - goto out;; + goto out; card->options.performance_stats = i; if (i == 0) memset(&card->perf_stats, 0, diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 847e8797073..7a7a1b66478 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -849,8 +849,6 @@ static int qeth_l2_open(struct net_device *dev) card->state = CARD_STATE_UP; netif_start_queue(dev); - if (!card->lan_online && netif_carrier_ok(dev)) - netif_carrier_off(dev); if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { napi_enable(&card->napi); napi_schedule(&card->napi); @@ -1013,13 +1011,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) dev_warn(&card->gdev->dev, "The LAN is offline\n"); card->lan_online = 0; - goto out; + goto contin; } rc = -ENODEV; goto out_remove; } else card->lan_online = 1; +contin: if ((card->info.type == QETH_CARD_TYPE_OSD) || (card->info.type == QETH_CARD_TYPE_OSX)) /* configure isolation level */ @@ -1038,7 +1037,10 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } card->state = CARD_STATE_SOFTSETUP; - netif_carrier_on(card->dev); + if (card->lan_online) + netif_carrier_on(card->dev); + else + netif_carrier_off(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); if (recover_flag == CARD_STATE_RECOVER) { @@ -1055,7 +1057,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); -out: mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return 0; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 74d1401a5d5..e227e465bfc 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -30,6 +30,7 @@ #include "qeth_l3.h" + static int qeth_l3_set_offline(struct ccwgroup_device *); static int qeth_l3_recover(void *); static int qeth_l3_stop(struct net_device *); @@ -455,8 +456,11 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "sdiplist"); QETH_CARD_HEX(card, 2, &card, sizeof(void *)); - if (card->options.sniffer) + if ((card->state != CARD_STATE_UP && + card->state != CARD_STATE_SOFTSETUP) || card->options.sniffer) { return; + } + spin_lock_irqsave(&card->ip_lock, flags); tbd_list = card->ip_tbd_list; card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); @@ -1796,7 +1800,8 @@ static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) char buf[MAX_ADDR_LEN]; QETH_CARD_TEXT(card, 4, "addmc"); - for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { + for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; + im4 = rcu_dereference(im4->next_rcu)) { qeth_l3_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev); ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); if (!ipm) @@ -1828,9 +1833,9 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card) in_dev = in_dev_get(netdev); if (!in_dev) continue; - read_lock(&in_dev->mc_list_lock); + rcu_read_lock(); qeth_l3_add_mc(card, in_dev); - read_unlock(&in_dev->mc_list_lock); + rcu_read_unlock(); in_dev_put(in_dev); } } @@ -1843,10 +1848,10 @@ static void qeth_l3_add_multicast_ipv4(struct qeth_card *card) in4_dev = in_dev_get(card->dev); if (in4_dev == NULL) return; - read_lock(&in4_dev->mc_list_lock); + rcu_read_lock(); qeth_l3_add_mc(card, in4_dev); qeth_l3_add_vlan_mc(card); - read_unlock(&in4_dev->mc_list_lock); + rcu_read_unlock(); in_dev_put(in4_dev); } @@ -2454,22 +2459,46 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) return rc; } -static void qeth_l3_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo, - struct qeth_arp_query_data *qdata, int entry_size, - int uentry_size) +static __u32 get_arp_entry_size(struct qeth_card *card, + struct qeth_arp_query_data *qdata, + struct qeth_arp_entrytype *type, __u8 strip_entries) { - char *entry_ptr; - char *uentry_ptr; - int i; + __u32 rc; + __u8 is_hsi; - entry_ptr = (char *)&qdata->data; - uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset); - for (i = 0; i < qdata->no_entries; ++i) { - /* strip off 32 bytes "media specific information" */ - memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32); - entry_ptr += entry_size; - uentry_ptr += uentry_size; + is_hsi = qdata->reply_bits == 5; + if (type->ip == QETHARP_IP_ADDR_V4) { + QETH_CARD_TEXT(card, 4, "arpev4"); + if (strip_entries) { + rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5_short) : + sizeof(struct qeth_arp_qi_entry7_short); + } else { + rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5) : + sizeof(struct qeth_arp_qi_entry7); + } + } else if (type->ip == QETHARP_IP_ADDR_V6) { + QETH_CARD_TEXT(card, 4, "arpev6"); + if (strip_entries) { + rc = is_hsi ? + sizeof(struct qeth_arp_qi_entry5_short_ipv6) : + sizeof(struct qeth_arp_qi_entry7_short_ipv6); + } else { + rc = is_hsi ? + sizeof(struct qeth_arp_qi_entry5_ipv6) : + sizeof(struct qeth_arp_qi_entry7_ipv6); + } + } else { + QETH_CARD_TEXT(card, 4, "arpinv"); + rc = 0; } + + return rc; +} + +static int arpentry_matches_prot(struct qeth_arp_entrytype *type, __u16 prot) +{ + return (type->ip == QETHARP_IP_ADDR_V4 && prot == QETH_PROT_IPV4) || + (type->ip == QETHARP_IP_ADDR_V6 && prot == QETH_PROT_IPV6); } static int qeth_l3_arp_query_cb(struct qeth_card *card, @@ -2478,72 +2507,77 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card, struct qeth_ipa_cmd *cmd; struct qeth_arp_query_data *qdata; struct qeth_arp_query_info *qinfo; - int entry_size; - int uentry_size; int i; + int e; + int entrybytes_done; + int stripped_bytes; + __u8 do_strip_entries; - QETH_CARD_TEXT(card, 4, "arpquecb"); + QETH_CARD_TEXT(card, 3, "arpquecb"); qinfo = (struct qeth_arp_query_info *) reply->param; cmd = (struct qeth_ipa_cmd *) data; + QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.prot_version); if (cmd->hdr.return_code) { - QETH_CARD_TEXT_(card, 4, "qaer1%i", cmd->hdr.return_code); + QETH_CARD_TEXT(card, 4, "arpcberr"); + QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code); return 0; } if (cmd->data.setassparms.hdr.return_code) { cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code; - QETH_CARD_TEXT_(card, 4, "qaer2%i", cmd->hdr.return_code); + QETH_CARD_TEXT(card, 4, "setaperr"); + QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code); return 0; } qdata = &cmd->data.setassparms.data.query_arp; - switch (qdata->reply_bits) { - case 5: - uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5); - if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) - uentry_size = sizeof(struct qeth_arp_qi_entry5_short); - break; - case 7: - /* fall through to default */ - default: - /* tr is the same as eth -> entry7 */ - uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7); - if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) - uentry_size = sizeof(struct qeth_arp_qi_entry7_short); - break; - } - /* check if there is enough room in userspace */ - if ((qinfo->udata_len - qinfo->udata_offset) < - qdata->no_entries * uentry_size){ - QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM); - cmd->hdr.return_code = -ENOMEM; - goto out_error; - } - QETH_CARD_TEXT_(card, 4, "anore%i", - cmd->data.setassparms.hdr.number_of_replies); - QETH_CARD_TEXT_(card, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no); QETH_CARD_TEXT_(card, 4, "anoen%i", qdata->no_entries); - if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) { - /* strip off "media specific information" */ - qeth_l3_copy_arp_entries_stripped(qinfo, qdata, entry_size, - uentry_size); - } else - /*copy entries to user buffer*/ - memcpy(qinfo->udata + qinfo->udata_offset, - (char *)&qdata->data, qdata->no_entries*uentry_size); + do_strip_entries = (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) > 0; + stripped_bytes = do_strip_entries ? QETH_QARP_MEDIASPECIFIC_BYTES : 0; + entrybytes_done = 0; + for (e = 0; e < qdata->no_entries; ++e) { + char *cur_entry; + __u32 esize; + struct qeth_arp_entrytype *etype; + + cur_entry = &qdata->data + entrybytes_done; + etype = &((struct qeth_arp_qi_entry5 *) cur_entry)->type; + if (!arpentry_matches_prot(etype, cmd->hdr.prot_version)) { + QETH_CARD_TEXT(card, 4, "pmis"); + QETH_CARD_TEXT_(card, 4, "%i", etype->ip); + break; + } + esize = get_arp_entry_size(card, qdata, etype, + do_strip_entries); + QETH_CARD_TEXT_(card, 5, "esz%i", esize); + if (!esize) + break; + + if ((qinfo->udata_len - qinfo->udata_offset) < esize) { + QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM); + cmd->hdr.return_code = -ENOMEM; + goto out_error; + } - qinfo->no_entries += qdata->no_entries; - qinfo->udata_offset += (qdata->no_entries*uentry_size); + memcpy(qinfo->udata + qinfo->udata_offset, + &qdata->data + entrybytes_done + stripped_bytes, + esize); + entrybytes_done += esize + stripped_bytes; + qinfo->udata_offset += esize; + ++qinfo->no_entries; + } /* check if all replies received ... */ if (cmd->data.setassparms.hdr.seq_no < cmd->data.setassparms.hdr.number_of_replies) return 1; + QETH_CARD_TEXT_(card, 4, "nove%i", qinfo->no_entries); memcpy(qinfo->udata, &qinfo->no_entries, 4); /* keep STRIP_ENTRIES flag so the user program can distinguish * stripped entries from normal ones */ if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES; memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET, &qdata->reply_bits, 2); + QETH_CARD_TEXT_(card, 4, "rc%i", 0); return 0; out_error: i = 0; @@ -2566,45 +2600,86 @@ static int qeth_l3_send_ipa_arp_cmd(struct qeth_card *card, reply_cb, reply_param); } -static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) +static int qeth_l3_query_arp_cache_info(struct qeth_card *card, + enum qeth_prot_versions prot, + struct qeth_arp_query_info *qinfo) { struct qeth_cmd_buffer *iob; - struct qeth_arp_query_info qinfo = {0, }; + struct qeth_ipa_cmd *cmd; int tmp; int rc; + QETH_CARD_TEXT_(card, 3, "qarpipv%i", prot); + + iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING, + IPA_CMD_ASS_ARP_QUERY_INFO, + sizeof(struct qeth_arp_query_data) - sizeof(char), + prot); + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + cmd->data.setassparms.data.query_arp.request_bits = 0x000F; + cmd->data.setassparms.data.query_arp.reply_bits = 0; + cmd->data.setassparms.data.query_arp.no_entries = 0; + rc = qeth_l3_send_ipa_arp_cmd(card, iob, + QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN, + qeth_l3_arp_query_cb, (void *)qinfo); + if (rc) { + tmp = rc; + QETH_DBF_MESSAGE(2, + "Error while querying ARP cache on %s: %s " + "(0x%x/%d)\n", QETH_CARD_IFNAME(card), + qeth_l3_arp_get_error_cause(&rc), tmp, tmp); + } + + return rc; +} + +static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) +{ + struct qeth_arp_query_info qinfo = {0, }; + int rc; + QETH_CARD_TEXT(card, 3, "arpquery"); if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ IPA_ARP_PROCESSING)) { - return -EOPNOTSUPP; + QETH_CARD_TEXT(card, 3, "arpqnsup"); + rc = -EOPNOTSUPP; + goto out; } /* get size of userspace buffer and mask_bits -> 6 bytes */ - if (copy_from_user(&qinfo, udata, 6)) - return -EFAULT; + if (copy_from_user(&qinfo, udata, 6)) { + rc = -EFAULT; + goto out; + } qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL); - if (!qinfo.udata) - return -ENOMEM; + if (!qinfo.udata) { + rc = -ENOMEM; + goto out; + } qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET; - iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING, - IPA_CMD_ASS_ARP_QUERY_INFO, - sizeof(int), QETH_PROT_IPV4); - - rc = qeth_l3_send_ipa_arp_cmd(card, iob, - QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN, - qeth_l3_arp_query_cb, (void *)&qinfo); + rc = qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV4, &qinfo); if (rc) { - tmp = rc; - QETH_DBF_MESSAGE(2, "Error while querying ARP cache on %s: %s " - "(0x%x/%d)\n", QETH_CARD_IFNAME(card), - qeth_l3_arp_get_error_cause(&rc), tmp, tmp); if (copy_to_user(udata, qinfo.udata, 4)) rc = -EFAULT; + goto free_and_out; } else { - if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) +#ifdef CONFIG_QETH_IPV6 + if (qinfo.mask_bits & QETH_QARP_WITH_IPV6) { + /* fails in case of GuestLAN QDIO mode */ + qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV6, + &qinfo); + } +#endif + if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) { + QETH_CARD_TEXT(card, 4, "qactf"); rc = -EFAULT; + goto free_and_out; + } + QETH_CARD_TEXT_(card, 4, "qacts"); } +free_and_out: kfree(qinfo.udata); +out: return rc; } @@ -2938,6 +3013,7 @@ static void qeth_tso_fill_header(struct qeth_card *card, /*fix header to TSO values ...*/ hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; + hdr->hdr.hdr.l3.length = skb->len - sizeof(struct qeth_hdr_tso); /*set values which are fix for the first approach ...*/ hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); hdr->ext.imb_hdr_no = 1; @@ -3039,7 +3115,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_pull(new_skb, ETH_HLEN); } - if (ipv == 6 && card->vlangrp && + if (ipv != 4 && card->vlangrp && vlan_tx_tag_present(new_skb)) { skb_push(new_skb, VLAN_HLEN); skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); @@ -3176,8 +3252,6 @@ static int qeth_l3_open(struct net_device *dev) card->state = CARD_STATE_UP; netif_start_queue(dev); - if (!card->lan_online && netif_carrier_ok(dev)) - netif_carrier_off(dev); if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { napi_enable(&card->napi); napi_schedule(&card->napi); @@ -3449,13 +3523,14 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) dev_warn(&card->gdev->dev, "The LAN is offline\n"); card->lan_online = 0; - goto out; + goto contin; } rc = -ENODEV; goto out_remove; } else card->lan_online = 1; +contin: rc = qeth_l3_setadapter_parms(card); if (rc) QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); @@ -3480,10 +3555,13 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } card->state = CARD_STATE_SOFTSETUP; - netif_carrier_on(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_l3_set_ip_addr_list(card); + if (card->lan_online) + netif_carrier_on(card->dev); + else + netif_carrier_off(card->dev); if (recover_flag == CARD_STATE_RECOVER) { if (recovery_mode) qeth_l3_open(card->dev); @@ -3496,7 +3574,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); -out: mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return 0; diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 044fb22718d..51c666fb67a 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -45,8 +45,8 @@ static char *init_device; module_param_named(device, init_device, charp, 0400); MODULE_PARM_DESC(device, "specify initial device"); -static struct kmem_cache *zfcp_cache_hw_align(const char *name, - unsigned long size) +static struct kmem_cache * __init zfcp_cache_hw_align(const char *name, + unsigned long size) { return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL); } @@ -311,8 +311,7 @@ int zfcp_status_read_refill(struct zfcp_adapter *adapter) if (zfcp_fsf_status_read(adapter->qdio)) { if (atomic_read(&adapter->stat_miss) >= adapter->stat_read_buf_num) { - zfcp_erp_adapter_reopen(adapter, 0, "axsref1", - NULL); + zfcp_erp_adapter_reopen(adapter, 0, "axsref1"); return 1; } break; @@ -459,7 +458,7 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter) sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs); zfcp_erp_thread_kill(adapter); - zfcp_dbf_adapter_unregister(adapter->dbf); + zfcp_dbf_adapter_unregister(adapter); zfcp_qdio_destroy(adapter->qdio); zfcp_ccw_adapter_put(adapter); /* final put to release */ diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 0833c2b51e3..4f7852dd30c 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -48,7 +48,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev) zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, - "ccresu2", NULL); + "ccresu2"); zfcp_erp_wait(adapter); flush_work(&adapter->scan_work); @@ -182,7 +182,7 @@ static int zfcp_ccw_set_offline(struct ccw_device *cdev) if (!adapter) return 0; - zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); + zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1"); zfcp_erp_wait(adapter); zfcp_ccw_adapter_put(adapter); @@ -207,24 +207,24 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event) switch (event) { case CIO_GONE: dev_warn(&cdev->dev, "The FCP device has been detached\n"); - zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL); + zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1"); break; case CIO_NO_PATH: dev_warn(&cdev->dev, "The CHPID for the FCP device is offline\n"); - zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL); + zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2"); break; case CIO_OPER: dev_info(&cdev->dev, "The FCP device is operational again\n"); zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, - "ccnoti4", NULL); + "ccnoti4"); break; case CIO_BOXED: dev_warn(&cdev->dev, "The FCP device did not respond within " "the specified time\n"); - zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL); + zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5"); break; } @@ -243,7 +243,7 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev) if (!adapter) return; - zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); + zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1"); zfcp_erp_wait(adapter); zfcp_erp_thread_kill(adapter); diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index d692e229ecb..46342fee394 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -288,7 +288,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter) (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, - "cfaac_1", NULL); + "cfaac_1"); } read_unlock_irqrestore(&adapter->port_list_lock, flags); @@ -299,7 +299,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter) (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, - "cfaac_2", NULL); + "cfaac_2"); } } @@ -426,7 +426,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL); + zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6"); return -EACCES; } @@ -437,7 +437,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL); + zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8"); return -EACCES; } diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 2cdd6b28ff7..96d1462e0bf 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -3,7 +3,7 @@ * * Debug traces for zfcp. * - * Copyright IBM Corporation 2002, 2009 + * Copyright IBM Corporation 2002, 2010 */ #define KMSG_COMPONENT "zfcp" @@ -22,980 +22,392 @@ module_param(dbfsize, uint, 0400); MODULE_PARM_DESC(dbfsize, "number of pages for each debug feature area (default 4)"); -static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len, - int level, char *from, int from_len) +static inline unsigned int zfcp_dbf_plen(unsigned int offset) { - int offset; - struct zfcp_dbf_dump *dump = to; - int room = to_len - sizeof(*dump); - - for (offset = 0; offset < from_len; offset += dump->size) { - memset(to, 0, to_len); - strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); - dump->total_size = from_len; - dump->offset = offset; - dump->size = min(from_len - offset, room); - memcpy(dump->data, from + offset, dump->size); - debug_event(dbf, level, dump, dump->size + sizeof(*dump)); - } + return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC; } -static void zfcp_dbf_tag(char **p, const char *label, const char *tag) +static inline +void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area, + u64 req_id) { - int i; - - *p += sprintf(*p, "%-24s", label); - for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) - *p += sprintf(*p, "%c", tag[i]); - *p += sprintf(*p, "\n"); -} + struct zfcp_dbf_pay *pl = &dbf->pay_buf; + u16 offset = 0, rec_length; -static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2) -{ - *buf += sprintf(*buf, "%-24s%s\n", s1, s2); -} + spin_lock(&dbf->pay_lock); + memset(pl, 0, sizeof(*pl)); + pl->fsf_req_id = req_id; + memcpy(pl->area, area, ZFCP_DBF_TAG_LEN); -static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...) -{ - va_list arg; + while (offset < length) { + rec_length = min((u16) ZFCP_DBF_PAY_MAX_REC, + (u16) (length - offset)); + memcpy(pl->data, data + offset, rec_length); + debug_event(dbf->pay, 1, pl, zfcp_dbf_plen(rec_length)); - *buf += sprintf(*buf, "%-24s", s); - va_start(arg, format); - *buf += vsprintf(*buf, format, arg); - va_end(arg); - *buf += sprintf(*buf, "\n"); -} - -static void zfcp_dbf_outd(char **p, const char *label, char *buffer, - int buflen, int offset, int total_size) -{ - if (!offset) - *p += sprintf(*p, "%-24s ", label); - while (buflen--) { - if (offset > 0) { - if ((offset % 32) == 0) - *p += sprintf(*p, "\n%-24c ", ' '); - else if ((offset % 4) == 0) - *p += sprintf(*p, " "); - } - *p += sprintf(*p, "%02x", *buffer++); - if (++offset == total_size) { - *p += sprintf(*p, "\n"); - break; - } + offset += rec_length; + pl->counter++; } - if (!total_size) - *p += sprintf(*p, "\n"); -} -static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view, - int area, debug_entry_t *entry, char *out_buf) -{ - struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); - struct timespec t; - char *p = out_buf; - - if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { - stck_to_timespec(entry->id.stck, &t); - zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu", - t.tv_sec, t.tv_nsec); - zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); - } else { - zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset, - dump->total_size); - if ((dump->offset + dump->size) == dump->total_size) - p += sprintf(p, "\n"); - } - return p - out_buf; + spin_unlock(&dbf->pay_lock); } -void _zfcp_dbf_hba_fsf_response(const char *tag2, int level, - struct zfcp_fsf_req *fsf_req, - struct zfcp_dbf *dbf) +/** + * zfcp_dbf_hba_fsf_res - trace event for fsf responses + * @tag: tag indicating which kind of unsolicited status has been received + * @req: request for which a response was received + */ +void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) { - struct fsf_qtcb *qtcb = fsf_req->qtcb; - union fsf_prot_status_qual *prot_status_qual = - &qtcb->prefix.prot_status_qual; - union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; - struct scsi_cmnd *scsi_cmnd; - struct zfcp_port *port; - struct zfcp_unit *unit; - struct zfcp_send_els *send_els; - struct zfcp_dbf_hba_record *rec = &dbf->hba_buf; - struct zfcp_dbf_hba_record_response *response = &rec->u.response; + struct zfcp_dbf *dbf = req->adapter->dbf; + struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix; + struct fsf_qtcb_header *q_head = &req->qtcb->header; + struct zfcp_dbf_hba *rec = &dbf->hba_buf; unsigned long flags; spin_lock_irqsave(&dbf->hba_lock, flags); memset(rec, 0, sizeof(*rec)); - strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); - strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); - - response->fsf_command = fsf_req->fsf_command; - response->fsf_reqid = fsf_req->req_id; - response->fsf_seqno = fsf_req->seq_no; - response->fsf_issued = fsf_req->issued; - response->fsf_prot_status = qtcb->prefix.prot_status; - response->fsf_status = qtcb->header.fsf_status; - memcpy(response->fsf_prot_status_qual, - prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE); - memcpy(response->fsf_status_qual, - fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); - response->fsf_req_status = fsf_req->status; - response->sbal_first = fsf_req->qdio_req.sbal_first; - response->sbal_last = fsf_req->qdio_req.sbal_last; - response->sbal_response = fsf_req->qdio_req.sbal_response; - response->pool = fsf_req->pool != NULL; - response->erp_action = (unsigned long)fsf_req->erp_action; - - switch (fsf_req->fsf_command) { - case FSF_QTCB_FCP_CMND: - if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) - break; - scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; - if (scsi_cmnd) { - response->u.fcp.cmnd = (unsigned long)scsi_cmnd; - response->u.fcp.data_dir = - qtcb->bottom.io.data_direction; - } - break; - - case FSF_QTCB_OPEN_PORT_WITH_DID: - case FSF_QTCB_CLOSE_PORT: - case FSF_QTCB_CLOSE_PHYSICAL_PORT: - port = (struct zfcp_port *)fsf_req->data; - response->u.port.wwpn = port->wwpn; - response->u.port.d_id = port->d_id; - response->u.port.port_handle = qtcb->header.port_handle; - break; - - case FSF_QTCB_OPEN_LUN: - case FSF_QTCB_CLOSE_LUN: - unit = (struct zfcp_unit *)fsf_req->data; - port = unit->port; - response->u.unit.wwpn = port->wwpn; - response->u.unit.fcp_lun = unit->fcp_lun; - response->u.unit.port_handle = qtcb->header.port_handle; - response->u.unit.lun_handle = qtcb->header.lun_handle; - break; - - case FSF_QTCB_SEND_ELS: - send_els = (struct zfcp_send_els *)fsf_req->data; - response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id); - break; - - case FSF_QTCB_ABORT_FCP_CMND: - case FSF_QTCB_SEND_GENERIC: - case FSF_QTCB_EXCHANGE_CONFIG_DATA: - case FSF_QTCB_EXCHANGE_PORT_DATA: - case FSF_QTCB_DOWNLOAD_CONTROL_FILE: - case FSF_QTCB_UPLOAD_CONTROL_FILE: - break; - } - - debug_event(dbf->hba, level, rec, sizeof(*rec)); - /* have fcp channel microcode fixed to use as little as possible */ - if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) { - /* adjust length skipping trailing zeros */ - char *buf = (char *)qtcb + qtcb->header.log_start; - int len = qtcb->header.log_length; - for (; len && !buf[len - 1]; len--); - zfcp_dbf_hexdump(dbf->hba, rec, sizeof(*rec), level, buf, - len); + memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); + rec->id = ZFCP_DBF_HBA_RES; + rec->fsf_req_id = req->req_id; + rec->fsf_req_status = req->status; |