--- linux-2.4.26/drivers/s390/net/lcs.c.orig 2004-09-18 19:02:11.000000000 -0400 +++ linux-2.4.26/drivers/s390/net/lcs.c 2004-09-18 19:02:14.000000000 -0400 @@ -7,7 +7,7 @@ * Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) * Frank Pavlic (pavlic@de.ibm.com) * - * $Revision: 1.132.20.4 $ $Date: 2004/01/22 23:49:11 $ + * $Revision: 1.132.20.5 $ $Date: 2004/06/08 16:45:08 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -4023,18 +4023,38 @@ #endif #ifdef CONFIG_IP_MULTICAST -static int lcs_ip_event(struct notifier_block *this, +static int +lcs_drvr_globals_in_list(lcs_drvr_globals * drvr_globals) +{ + int in_list = FALSE; + + if (drvr_globals) { + spin_lock(&lcs_card_list_lock); + in_list = + is_in_list((list *) lcs_card_list, (list *) drvr_globals); + spin_unlock(&lcs_card_list_lock); + } + return (in_list); +} + +static int lcs_mc_event(struct notifier_block *this, unsigned long event,void *ptr) { + struct ip_mc_list *im = (struct ip_mc_list *) ptr; + struct net_device *dev = im->interface->dev; + struct lcs_drvr_globals *drvr_globals; + + drvr_globals = (struct lcs_drvr_globals *) dev->priv; + if (!lcs_drvr_globals_in_list(drvr_globals)) + return NOTIFY_DONE; /* lcs_set_multicast_list locks appropriately */ - if (event==NETDEV_CHANGE) - lcs_set_multicast_list((struct net_device *)ptr); + lcs_set_multicast_list(dev); return NOTIFY_DONE; } -static struct notifier_block lcs_ip_notifier = { - lcs_ip_event, +static struct notifier_block lcs_mc_notifier = { + lcs_mc_event, 0 }; #endif @@ -4044,7 +4064,7 @@ lcs_cleanup(void) { #ifdef CONFIG_IP_MULTICAST - unregister_inetaddr_notifier(&lcs_ip_notifier); + unregister_multicast_notifier(&lcs_mc_notifier); #endif #if LCS_CHANDEV chandev_unregister(lcs_probe, TRUE); @@ -4076,7 +4096,7 @@ #else "compiled into kernel " #endif - " $Revision: 1.132.20.4 $ $Date: 2004/01/22 23:49:11 $ \n" + " $Revision: 1.132.20.5 $ $Date: 2004/06/08 16:45:08 $ \n" #if LCS_CHANDEV "with" #else @@ -4118,7 +4138,7 @@ #endif #ifdef CONFIG_IP_MULTICAST - if (register_inetaddr_notifier(&lcs_ip_notifier)) { + if (register_multicast_notifier(&lcs_mc_notifier)) { lcs_bad_news("register_inetaddr_notifier failed, maybe not " \ "all multicast addresses will be registered\n"); } --- linux-2.4.26/drivers/s390/net/qeth.c.orig 2004-09-18 19:02:12.000000000 -0400 +++ linux-2.4.26/drivers/s390/net/qeth.c 2004-09-18 19:02:14.000000000 -0400 @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth.c ($Revision: 1.337.4.23 $) + * linux/drivers/s390/net/qeth.c ($Revision: 1.337.4.24 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -171,7 +171,7 @@ static int global_stay_in_mem=0; /****************** MODULE STUFF **********************************/ -#define VERSION_QETH_C "$Revision: 1.337.4.23 $" +#define VERSION_QETH_C "$Revision: 1.337.4.24 $" static const char *version="qeth S/390 OSA-Express driver (" \ VERSION_QETH_C "/" VERSION_QETH_H "/" VERSION_QETH_MPC_H QETH_VERSION_IPV6 QETH_VERSION_VLAN ")"; @@ -9848,24 +9848,17 @@ unsigned long event,void *ptr) { qeth_card_t *card; - struct in_ifaddr *ifa; - struct net_device *dev; + struct in_ifaddr *ifa=(struct in_ifaddr *)ptr; + struct net_device *dev = ifa->ifa_dev->dev; char dbf_text[15]; sprintf(dbf_text,"ipevent"); QETH_DBF_TEXT3(0,trace,dbf_text); QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); - if (event==NETDEV_CHANGE) { - dev=(struct net_device *)ptr; - } else { - ifa=(struct in_ifaddr *)ptr; - dev = ifa->ifa_dev->dev; sprintf(dbf_text,"%08x",ifa->ifa_address); QETH_DBF_TEXT3(0,trace,dbf_text); sprintf(dbf_text,"%08x",ifa->ifa_mask); QETH_DBF_TEXT3(0,trace,dbf_text); - } - QETH_DBF_HEX3(0,trace,&dev,sizeof(void*)); #ifdef QETH_VLAN if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) @@ -9887,23 +9880,16 @@ unsigned long event,void *ptr) { qeth_card_t *card; - struct inet6_ifaddr *ifa; - struct net_device *dev; + struct inet6_ifaddr *ifa=(struct inet6_ifaddr *)ptr; + struct net_device *dev = ifa->idev->dev; char dbf_text[15]; sprintf(dbf_text,"ip6event"); QETH_DBF_TEXT3(0,trace,dbf_text); QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); - if (event==NETDEV_CHANGE) { - dev=(struct net_device *)ptr; - } else { - ifa=(struct inet6_ifaddr *)ptr; - dev = ifa->idev->dev; QETH_DBF_HEX3(0,trace,ifa->addr.s6_addr,QETH_DBF_TRACE_LEN); QETH_DBF_HEX3(0,trace,ifa->addr.s6_addr+QETH_DBF_TRACE_LEN, QETH_DBF_TRACE_LEN); - } - QETH_DBF_HEX3(0,trace,&dev,sizeof(void*)); #ifdef QETH_VLAN if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) @@ -9920,8 +9906,63 @@ return NOTIFY_DONE; } + +static int +qeth_multicast6_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + qeth_card_t *card; + struct ifmcaddr6 *mc = (struct ifmcaddr6 *) ptr; + struct net_device *dev = mc->idev->dev; + char dbf_text[15]; + + sprintf(dbf_text,"mc6event"); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); +#ifdef QETH_VLAN + if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv; + else +#endif + card=(qeth_card_t *)dev->priv; + if (qeth_does_card_exist(card)) { + QETH_DBF_HEX3(0,trace,&card,sizeof(void*)); + qeth_save_dev_flag_state(card); + qeth_start_softsetup_thread(card); + } + + return NOTIFY_DONE; +} + #endif /* QETH_IPV6 */ +static int +qeth_multicast_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + qeth_card_t *card; + struct ip_mc_list *mc = (struct ip_mc_list *) ptr; + struct net_device *dev = mc->interface->dev; + char dbf_text[15]; + + sprintf(dbf_text,"mc4event"); + QETH_DBF_TEXT3(0,trace,dbf_text); + QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long)); +#ifdef QETH_VLAN + if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV) + card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv; + else +#endif + card=(qeth_card_t *)dev->priv; + if (qeth_does_card_exist(card)) { + QETH_DBF_HEX3(0,trace,&card,sizeof(void*)); + qeth_save_dev_flag_state(card); + qeth_start_softsetup_thread(card); + } + + return NOTIFY_DONE; +} + static int qeth_reboot_event(struct notifier_block *this, unsigned long event,void *ptr) { @@ -9963,11 +10004,22 @@ 0 }; +static struct notifier_block qeth_mc_notifier = { + qeth_multicast_event, + 0 +}; + #ifdef QETH_IPV6 static struct notifier_block qeth_ip6_notifier = { qeth_ip6_event, 0 }; + +static struct notifier_block qeth_mc6_notifier = { + qeth_multicast6_event, + 0 +}; + #endif /* QETH_IPV6 */ static struct notifier_block qeth_reboot_notifier = { @@ -9982,10 +10034,11 @@ QETH_DBF_TEXT5(0,trace,"regnotif"); /* register to be notified on events */ r=register_netdevice_notifier(&qeth_dev_notifier); - r=register_inetaddr_notifier(&qeth_ip_notifier); + r=register_multicast_notifier(&qeth_mc_notifier); #ifdef QETH_IPV6 r=register_inet6addr_notifier(&qeth_ip6_notifier); + r=register_multicast6_notifier(&qeth_mc6_notifier); #endif /* QETH_IPV6 */ r=register_reboot_notifier(&qeth_reboot_notifier); } @@ -9998,8 +10051,10 @@ QETH_DBF_TEXT5(0,trace,"unregnot"); r=unregister_netdevice_notifier(&qeth_dev_notifier); r=unregister_inetaddr_notifier(&qeth_ip_notifier); + r=unregister_multicast_notifier(&qeth_mc_notifier); #ifdef QETH_IPV6 r=unregister_inet6addr_notifier(&qeth_ip6_notifier); + r=unregister_multicast6_notifier(&qeth_mc6_notifier); #endif /* QETH_IPV6 */ r=unregister_reboot_notifier(&qeth_reboot_notifier); } --- linux-2.4.26/drivers/s390/qdio.c.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/drivers/s390/qdio.c 2004-09-18 19:02:14.000000000 -0400 @@ -57,7 +57,7 @@ #include -#define VERSION_QDIO_C "$Revision: 1.145.4.5 $" +#define VERSION_QDIO_C "$Revision: 1.145.4.6 $" /****************** MODULE PARAMETER VARIABLES ********************/ MODULE_AUTHOR("Utz Bacher "); @@ -746,7 +746,7 @@ if (f==first_not_to_check) goto out; slsbyte=slsb[f_mod_no]; - /* the hydra has not fetched the output yet */ + /* the card has not fetched the output yet */ if (slsbyte==SLSB_CU_OUTPUT_PRIMED) { #ifdef QDIO_DBF_LIKE_HELL QDIO_DBF_TEXT5(0,trace,"outpprim"); @@ -754,7 +754,7 @@ goto out; } - /* the hydra got it */ + /* the card got it */ if (slsbyte==SLSB_P_OUTPUT_EMPTY) { atomic_dec(&q->number_of_buffers_used); f++; @@ -1236,7 +1236,7 @@ no_used=atomic_read(&q->number_of_buffers_used); - /* we need that one for synchronization with Hydra, as Hydra + /* we need that one for synchronization with the OSA/FCP card, as it * does a kind of PCI avoidance */ SYNC_MEMORY; @@ -1387,7 +1387,7 @@ } /* maybe we have to do work on our outbound queues... at least - * we have to check Hydra outbound-int-capable thinint-capable + * we have to check for outbound-int-capable thinint-capable * queues */ if (q->hydra_gives_outbound_pcis) { irq_ptr=(qdio_irq_t*)q->irq_ptr; @@ -2386,7 +2386,7 @@ if (result) { QDIO_PRINT_WARN("CHSC returned cc %i. Won't use adapter " \ - "interrupts for any Hydra.\n",result); + "interrupts for any QDIO device.\n",result); result=0; goto out; } @@ -2395,7 +2395,8 @@ store_qdio_data_response.response_code; if (i!=1) { QDIO_PRINT_WARN("Was not able to determine general " \ - "characteristics of all Hydras aboard.\n"); + "characteristics of all QDIO devices " \ + "aboard.\n"); result=0; goto out; } --- linux-2.4.26/drivers/s390/s390io.c.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/drivers/s390/s390io.c 2004-09-18 19:02:14.000000000 -0400 @@ -1,7 +1,7 @@ /* * drivers/s390/s390io.c * S/390 common I/O routines - * $Revision: 1.247.4.3 $ + * $Revision: 1.247.4.4 $ * * S390 version * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, @@ -3043,7 +3043,16 @@ if (!ioinfo[irq]->ui.flags.ready) return (ending_status); - memcpy (udp, &(ioinfo[irq]->devstat), sdevstat); + /* + * Special case: We got a deferred cc 3 on a basic sense. + * We have to notify the device driver of the former unit + * check, but must not confuse it by calling it with the status + * for the failed basic sense. + */ + if (ioinfo[irq]->ui.flags.w4sense) + ioinfo[irq]->ui.flags.w4sense = 0; + else + memcpy (udp, &(ioinfo[irq]->devstat), sdevstat); ioinfo[irq]->devstat.intparm = 0; --- linux-2.4.26/drivers/s390/scsi/zfcp.h.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/drivers/s390/scsi/zfcp.h 2004-09-18 19:02:14.000000000 -0400 @@ -27,7 +27,6 @@ #define ZFCP_LOW_MEM_CREDITS #define ZFCP_STAT_REQSIZES #define ZFCP_STAT_QUEUES -#define ZFCP_STAT_REQ_QUEUE_LOCK #define ZFCP_PARSE_ERR_BUF_SIZE 100 @@ -565,14 +564,6 @@ } zfcp_port_t; -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK -typedef struct _zfcp_lock_meter { - unsigned long long time; - rwlock_t lock; -} zfcp_lock_meter_t; -#endif - - /* QDIO request/response queue */ typedef struct _zfcp_qdio_queue { /* SBALs */ @@ -583,9 +574,6 @@ atomic_t free_count; /* lock for critical operations on queue */ rwlock_t queue_lock; -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - zfcp_lock_meter_t lock_meter; -#endif /* outbound queue only, SBALs since PCI indication */ int distance_from_int; } zfcp_qdio_queue_t; @@ -738,6 +726,17 @@ #ifdef ZFCP_ERP_DEBUG_SINGLE_STEP struct semaphore erp_continue_sem; #endif /* ZFCP_ERP_DEBUG_SINGLE_STEP */ +#ifdef ZFCP_STAT_REQSIZES + struct list_head read_req_head; + struct list_head write_req_head; + rwlock_t stat_lock; + atomic_t stat_errors; + atomic_t stat_on; +#endif +#ifdef ZFCP_STAT_QUEUES + atomic_t outbound_queue_full; + atomic_t outbound_total; +#endif } zfcp_adapter_t; /* driver data */ @@ -769,23 +768,7 @@ struct proc_dir_entry *add_map_proc_file; /* buffer for parse error messages (don't want to put it on stack) */ unsigned char perrbuf[ZFCP_PARSE_ERR_BUF_SIZE]; - /* Debug Feature */ - debug_info_t *spinlock_dbf; atomic_t mem_count; -#ifdef ZFCP_STAT_REQSIZES - struct list_head read_req_head; - struct list_head write_req_head; - struct list_head read_sg_head; - struct list_head write_sg_head; - struct list_head read_sguse_head; - struct list_head write_sguse_head; - unsigned long stat_errors; - rwlock_t stat_lock; -#endif -#ifdef ZFCP_STAT_QUEUES - atomic_t outbound_queue_full; - atomic_t outbound_total; -#endif struct notifier_block reboot_notifier; atomic_t loglevel; #ifdef ZFCP_LOW_MEM_CREDITS @@ -817,42 +800,6 @@ unsigned int count; } zfcp_sg_list_t; -#define ZFCP_READ_LOCK(lock) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"rlock"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - read_lock(lock); \ - } - -#define ZFCP_READ_UNLOCK(lock) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"rulock"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - read_unlock(lock); \ - } - -#define ZFCP_READ_LOCK_IRQSAVE(lock, flags) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"rlocki"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - read_lock_irqsave(lock, flags); \ - } - -#define ZFCP_READ_UNLOCK_IRQRESTORE(lock, flags) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"rulocki"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - read_unlock_irqrestore(lock, flags); \ - } - extern zfcp_data_t zfcp_data; #ifdef ZFCP_LOW_MEM_CREDITS @@ -921,7 +868,7 @@ * this allows to remove excluded logs from the code by the preprocessor * (this is the last log level compiled in, higher log levels are removed) */ -#define ZFCP_LOG_LEVEL_LIMIT ZFCP_LOG_LEVEL_TRACE +#define ZFCP_LOG_LEVEL_LIMIT ZFCP_LOG_LEVEL_DEBUG /* nibbles of "loglevel" are used for particular purposes */ #define ZFCP_LOG_VALUE(zfcp_lognibble) \ @@ -1190,23 +1137,6 @@ #define ZFCP_FOR_EACH_UNIT(p,u) \ ZFCP_FOR_EACH_ENTITY(&(p)->unit_list_head,(u),zfcp_unit_t) -#define ZFCP_WRITE_LOCK_IRQSAVE(lock, flags) \ -{ \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"wlocki"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - write_lock_irqsave(lock, flags); \ -} - -#define ZFCP_WRITE_UNLOCK_IRQRESTORE(lock, flags) \ -{ \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"wulocki"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - write_unlock_irqrestore(lock, flags); \ -} /* Note, the leftmost status byte is common among adapter, port and unit --- linux-2.4.26/drivers/s390/scsi/zfcp_fsf.h.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/drivers/s390/scsi/zfcp_fsf.h 2004-09-18 19:02:14.000000000 -0400 @@ -1,5 +1,5 @@ /* - * $Id: zfcp_fsf.h,v 1.7.2.2 2004/03/26 13:10:31 maxim Exp $ + * $Id: zfcp_fsf.h,v 1.7.2.3 2004/05/19 13:08:06 mpeschke Exp $ * * header file for FCP adapter driver for IBM eServer zSeries * @@ -93,6 +93,7 @@ #define FSF_CONFLICTS_OVERRULED 0x00000058 #define FSF_PORT_BOXED 0x00000059 #define FSF_LUN_BOXED 0x0000005A +#define FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE 0x0000005B #define FSF_PAYLOAD_SIZE_MISMATCH 0x00000060 #define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061 #define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062 --- linux-2.4.26/drivers/s390/scsi/zfcp_main.c.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/drivers/s390/scsi/zfcp_main.c 2004-09-18 19:02:14.000000000 -0400 @@ -14,7 +14,7 @@ */ /* this drivers version (do not edit !!! generated and updated by cvs) */ -#define ZFCP_REVISION "$Revision: 1.31.2.3 $" +#define ZFCP_REVISION "$Revision: 1.31.2.10 $" #define ZFCP_QTCB_VERSION FSF_QTCB_CURRENT_VERSION @@ -38,7 +38,6 @@ #define ZFCP_STAT_REQSIZES #define ZFCP_STAT_QUEUES -#define ZFCP_STAT_REQ_QUEUE_LOCK // current implementation does not work due to proc_sema #undef ZFCP_ERP_DEBUG_SINGLE_STEP @@ -136,7 +135,7 @@ #define ZFCP_TYPE2_RECOVERY_TIME 8*HZ #ifdef ZFCP_STAT_REQSIZES -#define ZFCP_MAX_PROC_SIZE 4 * PAGE_SIZE +#define ZFCP_MAX_PROC_SIZE 3 * PAGE_SIZE #else #define ZFCP_MAX_PROC_SIZE PAGE_SIZE #endif @@ -187,6 +186,9 @@ #define ZFCP_RLS "rls" #define ZFCP_PDISC "pdisc" #define ZFCP_ADISC "adisc" +#define ZFCP_STAT_ON "stat on" +#define ZFCP_STAT_OFF "stat off" +#define ZFCP_STAT_RESET "stat reset" #define ZFCP_DID_MASK 0x00ffffff @@ -225,7 +227,7 @@ #define ZFCP_REQ_DBF_INDEX 1 #define ZFCP_REQ_DBF_AREAS 1 #define ZFCP_REQ_DBF_LENGTH 8 -#define ZFCP_REQ_DBF_LEVEL 1 +#define ZFCP_REQ_DBF_LEVEL DEBUG_OFF_LEVEL #define ZFCP_REQ_DBF_NAME "zfcp_req" #define ZFCP_CMD_DBF_INDEX 2 @@ -342,76 +344,6 @@ char *buf; } procbuf_t; -#define ZFCP_WRITE_LOCK(lock) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"wlock"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - write_lock(lock); \ - } - -#define ZFCP_WRITE_UNLOCK(lock) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"wulock"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - write_unlock(lock); \ - } - -#define ZFCP_WRITE_LOCK_IRQSAVE(lock, flags) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"wlocki"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - write_lock_irqsave(lock, flags); \ - } - -#define ZFCP_WRITE_UNLOCK_IRQRESTORE(lock, flags) \ - { \ - void *__sp_lock_addr=lock; \ - debug_text_event(zfcp_data.spinlock_dbf,3,"wulocki"); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sp_lock_addr, \ - sizeof(unsigned long)); \ - write_unlock_irqrestore(lock, flags); \ - } - - -#define ZFCP_UP(sema) \ - { \ - void *__sema_addr=sema; \ - char action[8]; \ - sprintf(action, "u%d", atomic_read(sema.count)); \ - debug_text_event(zfcp_data.spinlock_dbf,3,action); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sema_addr, \ - sizeof(unsigned long)); \ - up(sema); \ - } - -#define ZFCP_DOWN(sema) \ - { \ - void *__sema_addr=sema; \ - char action[8]; \ - sprintf(action, "d%d", atomic_read(sema.count)); \ - debug_text_event(zfcp_data.spinlock_dbf,3,action); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sema_addr, \ - sizeof(unsigned long)); \ - down(sema); \ - } - -#define ZFCP_DOWN_INTERRUPTIBLE(sema) \ - { \ - void *__sema_addr=sema; \ - char action[8]; \ - sprintf(action, "di%d", atomic_read(sema.count)); \ - debug_text_event(zfcp_data.spinlock_dbf,3,action); \ - debug_event(zfcp_data.spinlock_dbf,3,&__sema_addr, \ - sizeof(unsigned long)); \ - down_interruptible(sema); \ - } - /* * not yet optimal but useful: @@ -590,7 +522,7 @@ typedef struct _zfcp_statistics { struct list_head list; u32 num; - u32 occurrence; + u32 hits; } zfcp_statistics_t; #endif @@ -941,9 +873,6 @@ static zfcp_unit_t* zfcp_unit_lookup (zfcp_adapter_t*, int, int, int); -/* prototypes for functions performing paranoia checks */ -static int zfcp_paranoia_fsf_reqs(zfcp_adapter_t*, zfcp_fsf_req_t*); - /* prototypes for functions faking callbacks of lower layers */ inline void zfcp_scsi_process_and_clear_fake_queue(unsigned long); inline void zfcp_scsi_insert_into_fake_queue(zfcp_adapter_t *, @@ -1025,8 +954,6 @@ int zfcp_delete_unit_proc(zfcp_unit_t*); /* prototypes for initialisation functions */ -static int zfcp_dbf_register (void); -static void zfcp_dbf_unregister (void); static int zfcp_dio_register (void); /* prototypes for extended link services functions */ @@ -1146,34 +1073,16 @@ #ifdef ZFCP_STAT_REQSIZES -static int zfcp_statistics_init_all (void); -static int zfcp_statistics_clear_all (void); -static int zfcp_statistics_clear (struct list_head*); -static int zfcp_statistics_new (struct list_head*, u32); -static int zfcp_statistics_inc (struct list_head*, u32); -static int zfcp_statistics_print (struct list_head*, char*, char*, int, int); -#endif - -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK -#if 0 -static inline unsigned long long - zfcp_adjust_tod - (unsigned long long); -#endif -static inline unsigned long long - zfcp_lock_meter_init - (zfcp_lock_meter_t*); -static inline unsigned long long - zfcp_lock_meter_add - (zfcp_lock_meter_t*, - unsigned long long); -static inline int - zfcp_lock_meter_print_tod - (char*); -static inline int - zfcp_lock_meter_print_time - (zfcp_lock_meter_t*, - char*); +static int zfcp_statistics_clear + (zfcp_adapter_t*, struct list_head*); +static int zfcp_statistics_print + (zfcp_adapter_t*, struct list_head*, char*, char*, int, int); +static void zfcp_statistics_inc + (zfcp_adapter_t*, struct list_head*, u32); +static inline void zfcp_statistics_new + (zfcp_adapter_t*, struct list_head*, u32); +static inline void zfcp_statistics_sort + (struct list_head*, struct list_head*, zfcp_statistics_t*); #endif @@ -1443,7 +1352,7 @@ int i; unsigned long flags; - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->cmd_dbf_lock, flags); + write_lock_irqsave(&adapter->cmd_dbf_lock, flags); if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) { scsi_cmnd = fsf_req->data.send_fcp_command_task.scsi_cmnd; debug_text_event(adapter->cmd_dbf, level, "fsferror"); @@ -1460,7 +1369,7 @@ (char*)add_data + i, min(ZFCP_CMD_DBF_LENGTH, add_length - i)); } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->cmd_dbf_lock, flags); + write_unlock_irqrestore(&adapter->cmd_dbf_lock, flags); #endif } @@ -1475,7 +1384,7 @@ int level = ((host_byte(scsi_cmnd->result) != 0) ? 1 : 5); unsigned long flags; - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->cmd_dbf_lock, flags); + write_lock_irqsave(&adapter->cmd_dbf_lock, flags); debug_text_event(adapter->cmd_dbf, level, "hostbyte"); debug_text_event(adapter->cmd_dbf, level, text); debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof(u32)); @@ -1489,7 +1398,7 @@ debug_text_event(adapter->cmd_dbf, level, ""); debug_text_event(adapter->cmd_dbf, level, ""); } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->cmd_dbf_lock, flags); + write_unlock_irqrestore(&adapter->cmd_dbf_lock, flags); #endif } @@ -1567,18 +1476,6 @@ /* initialize map list */ INIT_LIST_HEAD(&zfcp_data.map_list_head); - /* create S/390 debug feature entries */ - if (zfcp_dbf_register()) { - ZFCP_LOG_INFO( - "warning: Could not allocate memory for " - "s390 debug-logging facility (debug feature), " - "continuing without.\n"); - } - -#ifdef ZFCP_STAT_REQSIZES - zfcp_statistics_init_all(); -#endif - #ifdef CONFIG_S390_SUPPORT retval = register_ioctl32_conversion( zfcp_cfdc_ioc.cmd, zfcp_cfdc_ioc.handler); @@ -1604,7 +1501,7 @@ /* Initialise proc semaphores */ sema_init(&zfcp_data.proc_sema,1); - ZFCP_DOWN(&zfcp_data.proc_sema); /* config changes protected by proc_sema */ + down(&zfcp_data.proc_sema); /* config changes protected by proc_sema */ #ifdef CONFIG_PROC_FS retval = zfcp_create_root_proc(); @@ -1669,7 +1566,7 @@ retval = 0; } - ZFCP_UP(&zfcp_data.proc_sema); /* release procfs */ + up(&zfcp_data.proc_sema); /* release procfs */ #ifdef ZFCP_CAUSE_ERRORS init_timer(&zfcp_force_error_timer); @@ -1713,10 +1610,6 @@ unregister_ioctl32_conversion(zfcp_cfdc_ioc.cmd); failed_ioctl32: #endif - zfcp_dbf_unregister(); -#ifdef ZFCP_STAT_REQSIZES - zfcp_statistics_clear_all(); -#endif ZFCP_LOG_NORMAL("error: Module could not be loaded.\n"); @@ -1773,9 +1666,9 @@ /* free all resources dynamically allocated */ /* block proc access to config */ - ZFCP_DOWN(&zfcp_data.proc_sema); + down(&zfcp_data.proc_sema); temp_ret=zfcp_config_cleanup(); - ZFCP_UP(&zfcp_data.proc_sema); + up(&zfcp_data.proc_sema); if (temp_ret) { ZFCP_LOG_NORMAL("bug: Could not free all memory " @@ -1790,16 +1683,10 @@ unregister_ioctl32_conversion(zfcp_cfdc_ioc.cmd); #endif - zfcp_dbf_unregister(); - #ifdef ZFCP_CAUSE_ERRORS del_timer(&zfcp_force_error_timer); #endif -#ifdef ZFCP_STAT_REQSIZES - zfcp_statistics_clear_all(); -#endif - ZFCP_LOG_TRACE("exit\n"); ZFCP_LOG_DEBUG("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); @@ -1830,7 +1717,7 @@ ZFCP_LOG_TRACE("enter\n"); /* block proc access to config (for rest of lifetime of this Linux) */ - ZFCP_DOWN(&zfcp_data.proc_sema); + down(&zfcp_data.proc_sema); zfcp_adapter_shutdown_all(); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -1976,67 +1863,6 @@ /* - * function: zfcp_dbf_register - * - * purpose: registers the module-wide debug feature entries and sets - * their respective level of detail - * - * returns: 0 on success - * -ENOMEM on failure of at least one dbf - */ -static int zfcp_dbf_register() -{ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - - int retval = 0; - - ZFCP_LOG_TRACE("enter\n"); - - zfcp_data.spinlock_dbf = debug_register("zfcp_lock", 4, 1, 8); - if (zfcp_data.spinlock_dbf) { - debug_register_view( - zfcp_data.spinlock_dbf, - &debug_hex_ascii_view); - debug_set_level(zfcp_data.spinlock_dbf, 4); - } else retval = -ENOMEM; - - ZFCP_LOG_TRACE("exit (%i)\n", retval); - - return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX -} - - -/* - * function: zfcp_dbf_unregister - * - * purpose: Removes module-wide debug feature entries and frees their - * memory - * - * returns: (void) - */ -static void zfcp_dbf_unregister() -{ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - - - ZFCP_LOG_TRACE("enter\n"); - - if (zfcp_data.spinlock_dbf) - debug_unregister(zfcp_data.spinlock_dbf); - - ZFCP_LOG_TRACE("exit\n"); - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX -} - - -/* * function: zfcp_config_cleanup * * purpose: must only be called after all adapters are properly shut down @@ -2069,16 +1895,16 @@ /* Note: no adapter_list_lock is needed as we have the proc_sema */ ZFCP_FOR_NEXT_ADAPTER (adapter, tmp_adapter) { - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + write_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_NEXT_PORT (adapter, port, tmp_port) { - ZFCP_WRITE_LOCK(&port->unit_list_lock); + write_lock(&port->unit_list_lock); ZFCP_FOR_NEXT_UNIT (port, unit, tmp_unit){ retval |= zfcp_unit_dequeue(unit); } - ZFCP_WRITE_UNLOCK(&port->unit_list_lock); + write_unlock(&port->unit_list_lock); retval |= zfcp_port_dequeue(port); } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + write_unlock_irqrestore(&adapter->port_list_lock, flags); retval |= zfcp_adapter_dequeue(adapter); } ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -2489,7 +2315,7 @@ devno, (unsigned long)adapter_p); - ZFCP_READ_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + read_lock_irqsave(&zfcp_data.adapter_list_lock, flags); ZFCP_FOR_EACH_ADAPTER(adapter) { if (adapter->devno == devno) { ZFCP_LOG_TRACE( @@ -2500,7 +2326,7 @@ break; } } - ZFCP_READ_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + read_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); if (retval == ZFCP_KNOWN) goto known_adapter; @@ -2548,9 +2374,6 @@ /* initialize lock of associated request queue */ rwlock_init(&adapter->request_queue.queue_lock); -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - zfcp_lock_meter_init(&adapter->request_queue.lock_meter); -#endif /* intitialise SCSI ER timer */ init_timer(&adapter->scsi_er_timer); @@ -2691,11 +2514,19 @@ adapter->specific_magic = ZFCP_MAGIC_ADAPTER; #endif +#ifdef ZFCP_STAT_REQSIZES + rwlock_init(&adapter->stat_lock); + atomic_set(&adapter->stat_on, 0); + atomic_set(&adapter->stat_errors, 0); + INIT_LIST_HEAD(&adapter->read_req_head); + INIT_LIST_HEAD(&adapter->write_req_head); +#endif + /* put allocated adapter at list tail */ - ZFCP_WRITE_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + write_lock_irqsave(&zfcp_data.adapter_list_lock, flags); list_add_tail(&adapter->list, &zfcp_data.adapter_list_head); zfcp_data.adapters++; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + write_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); sprintf(adapter->name, "0x%04x", adapter->devno); ASCEBC(adapter->name, strlen(adapter->name)); @@ -2814,11 +2645,11 @@ } /* sanity check: no pending FSF requests */ - ZFCP_READ_LOCK_IRQSAVE(&adapter->fsf_req_list_lock, flags); + read_lock_irqsave(&adapter->fsf_req_list_lock, flags); retval = !list_empty(&adapter->fsf_req_list_head); - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->fsf_req_list_lock, flags); + read_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); if (retval) { ZFCP_LOG_NORMAL( "bug: Adapter with devno 0x%04x is still in use, " @@ -2831,27 +2662,6 @@ goto out; } - /* paranoia checks */ - ZFCP_PARANOIA{ - zfcp_adapter_t *tmp; - /* consistency of adapter list in general */ - /* is specified adapter in list ? */ - ZFCP_FOR_EACH_ADAPTER(tmp) - if (tmp == adapter) - break; - if (tmp != adapter) { - /* inconsistency */ - ZFCP_LOG_NORMAL( - "bug: Adapter struct with devno 0x%04x not " - "in global adapter struct list " - "(debug info 0x%lx)\n", - adapter->devno, - (unsigned long)adapter); - retval = -EINVAL; - goto out; - } - } - /* remove specified adapter data structure from list */ list_del(&adapter->list); @@ -2865,7 +2675,12 @@ zfcp_data.adapters); retval = zfcp_erp_thread_kill(adapter); - + +#ifdef ZFCP_STAT_REQSIZES + zfcp_statistics_clear(adapter, &adapter->read_req_head); + zfcp_statistics_clear(adapter, &adapter->write_req_head); +#endif + zfcp_delete_adapter_proc(adapter); ZFCP_LOG_TRACE("Proc entry removed.\n"); @@ -2945,17 +2760,6 @@ (llui_t)wwpn, status); - /* sanity check: valid adapter data structure address */ - ZFCP_PARANOIA { - if (!adapter) { - ZFCP_LOG_NORMAL( - "bug: Pointer to the adapter struct is a null " - "pointer\n"); - retval = -EINVAL; - goto paranoia_failed; - } - } - /* to check that there is not a port with either this * SCSI ID or WWPN already in list */ @@ -2963,7 +2767,7 @@ check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN); if (check_scsi_id && check_wwpn) { - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { if ((port->scsi_id != scsi_id) && (port->wwpn != wwpn)) continue; @@ -2972,7 +2776,7 @@ "Port with SCSI ID 0x%x and WWPN 0x%016Lx already in list\n", scsi_id, (llui_t)wwpn); retval = ZFCP_KNOWN; - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); goto known_port; } ZFCP_LOG_NORMAL( @@ -2985,10 +2789,10 @@ (llui_t)port->wwpn, port->adapter->devno); retval = -EINVAL; - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); goto match_failed; } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); } /* @@ -3068,10 +2872,10 @@ } /* Port is allocated, enqueue it*/ - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock,flags); + write_lock_irqsave(&adapter->port_list_lock,flags); list_add_tail(&port->list, &adapter->port_list_head); adapter->ports++; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock,flags); + write_unlock_irqrestore(&adapter->port_list_lock,flags); atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); @@ -3095,7 +2899,6 @@ port_alloc_failed: match_failed: -paranoia_failed: port = NULL; known_port: @@ -3140,20 +2943,6 @@ goto out; } - /* paranoia check: valid "parent" adapter (simple check) */ - ZFCP_PARANOIA { - if (!port->adapter) { - ZFCP_LOG_NORMAL( - "bug: Port struct for port with SCSI-id 0x%x " - "contains an invalid pointer to its adapter " - "struct(debug info 0x%lx) \n", - port->scsi_id, - (unsigned long)port); - retval = -EINVAL; - goto out; - } - } - /* * sanity check: * leave if required list lock is not held, @@ -3182,28 +2971,6 @@ goto out; } - /* paranoia checks */ - ZFCP_PARANOIA { - zfcp_port_t *tmp; - /* is specified port in list ? */ - ZFCP_FOR_EACH_PORT(port->adapter, tmp) - if (tmp == port) - break; - if (tmp != port) { - /* inconsistency */ - ZFCP_LOG_NORMAL( - "bug: Port struct with SCSI-id 0x%x not " - "in port struct list " - "(debug info 0x%lx, 0x%lx)\n", - port->scsi_id, - (unsigned long)port, - (unsigned long)port->adapter); - - retval = -EINVAL; - goto out; - } - } - /* remove specified port data structure from list */ list_del(&port->list); @@ -3667,62 +3434,6 @@ /* - * function: zfcp_paranoia_fsf_reqs - * - * purpose: check sanity of FSF request list of specified adapter - * - * returns: 0 - no error condition - * !0 - error condition - * - * locks: adapter->fsf_req_list_lock of the associated adapter is - * assumed to be held by the calling routine - */ -static int zfcp_paranoia_fsf_reqs(zfcp_adapter_t *adapter, zfcp_fsf_req_t *req) -{ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_FSF - - zfcp_fsf_req_t *current_req = NULL; - int retval = 0; - - ZFCP_LOG_TRACE("enter (adapter=0x%lx)\n", (unsigned long)adapter); - - /* - * sanity check: - * leave if required list lock is not held, - * do not know whether it is held by the calling routine (required!) - * protecting this critical area or someone else (must not occur!), - * but a lock not held by anyone is definetely wrong - */ - if (!spin_is_locked(&adapter->fsf_req_list_lock)) { - ZFCP_LOG_NORMAL( - "bug: FSF request list lock not held\n"); - retval = -EPERM; - goto out; - } - - /* go through list, check magics and count fsf_reqs */ - ZFCP_FOR_EACH_FSFREQ(adapter, current_req) { - if (current_req == req) - goto out; - } - ZFCP_LOG_NORMAL( - "fsf_req 0x%lx not found in list of adapter with devno 0x%04x\n", - (unsigned long)req, - adapter->devno); - retval = -EINVAL; - -out: - ZFCP_LOG_TRACE("exit (%i)\n", retval); - - return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX -} - - -/* * function: zfcp_unit_enqueue * * purpose: enqueues a logical unit at the end of the unit list @@ -3754,23 +3465,12 @@ "enter (port=0x%lx scsi_lun=%i fcp_lun=0x%Lx)\n", (unsigned long)port, scsi_lun, (llui_t)fcp_lun); - /* sanity check: valid port data structure address */ - ZFCP_PARANOIA { - if (!port) { - ZFCP_LOG_NORMAL( - "bug: Pointer to a port struct is a null " - "pointer\n"); - retval = -EINVAL; - goto paranoia_failed; - } - } - /* * check that there is no unit with either this * SCSI LUN or FCP_LUN already in list * Note: Unlike for the adapter and the port, this is an error */ - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, unit) { if (unit->scsi_lun == scsi_lun) { ZFCP_LOG_NORMAL( @@ -3788,7 +3488,7 @@ break; } } - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); if (retval == -EINVAL) goto known_unit; @@ -3870,10 +3570,10 @@ } /* Unit is new and needs to be added to list */ - ZFCP_WRITE_LOCK_IRQSAVE(&port->unit_list_lock, flags); + write_lock_irqsave(&port->unit_list_lock, flags); list_add_tail(&unit->list, &port->unit_list_head); port->units++; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + write_unlock_irqrestore(&port->unit_list_lock, flags); /* also add unit to map list to get them in order of addition */ list_add_tail(&unit->map_list, &zfcp_data.map_list_head); @@ -3894,7 +3594,6 @@ ZFCP_KFREE(unit, sizeof(zfcp_unit_t)); unit_alloc_failed: -paranoia_failed: unit = NULL; known_unit: @@ -3939,21 +3638,6 @@ goto out; } - /* paranoia check: valid "parent" port (simple check) */ - ZFCP_PARANOIA { - if (!unit->port) { - ZFCP_LOG_NORMAL( - "bug: Unit struct for unit with SCSI LUN 0x%x " - "contains an invalid pointer to its adapter " - "struct(debug info 0x%lx, 0x%lx) \n", - unit->scsi_lun, - (unsigned long)unit, - (unsigned long)unit->port); - retval = -EINVAL; - goto out; - } - } - /* * sanity check: * leave if required list lock is not held, @@ -3969,27 +3653,6 @@ goto out; } - /* paranoia checks */ - ZFCP_PARANOIA { - zfcp_unit_t *tmp; - /* is specified unit in list ? */ - ZFCP_FOR_EACH_UNIT(unit->port, tmp) - if (tmp == unit) - break; - if (tmp != unit) { - /* inconsistency */ - ZFCP_LOG_NORMAL( - "bug: Unit struct with SCSI LUN 0x%x not " - "in unit struct list " - "(debug info 0x%lx, 0x%lx)\n", - unit->scsi_lun, - (unsigned long)unit, - (unsigned long)unit->port); - retval = -EINVAL; - goto out; - } - } - /* remove specified unit data structure from list */ list_del(&unit->list); @@ -4466,22 +4129,6 @@ len += sprintf(pbuf->buf+len,"\n"); }// if (proc_debug != 0) -#ifdef ZFCP_STAT_QUEUES - len += sprintf(pbuf->buf + len, "Outbound queue full: 0x%08x\n", - atomic_read(&zfcp_data.outbound_queue_full)); - len += sprintf(pbuf->buf + len, "Outbound requests: 0x%08x\n", - atomic_read(&zfcp_data.outbound_total)); -#endif -#ifdef ZFCP_STAT_REQSIZES - len += sprintf(pbuf->buf+len, "missed stats 0x%lx\n", zfcp_data.stat_errors); - len = zfcp_statistics_print(&zfcp_data.read_req_head, "rr", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); - len = zfcp_statistics_print(&zfcp_data.write_req_head, "wr", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); - len = zfcp_statistics_print(&zfcp_data.read_sg_head, "re", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); - len = zfcp_statistics_print(&zfcp_data.write_sg_head, "we", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); - len = zfcp_statistics_print(&zfcp_data.read_sguse_head, "rn", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); - len = zfcp_statistics_print(&zfcp_data.write_sguse_head, "wn", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); -#endif - pbuf->len = len; out: @@ -4558,12 +4205,12 @@ (unsigned long)inode, (unsigned long) buffer); - ZFCP_DOWN(&zfcp_data.proc_sema); + down(&zfcp_data.proc_sema); zfcp_data.proc_line = ZFCP_KMALLOC(ZFCP_MAX_PROC_LINE, GFP_KERNEL); if (zfcp_data.proc_line == NULL) { /* release semaphore on memory shortage */ - ZFCP_UP(&zfcp_data.proc_sema); + up(&zfcp_data.proc_sema); ZFCP_LOG_NORMAL("error: Not enough free memory for procfile" " input. Input will be ignored.\n"); @@ -4636,7 +4283,7 @@ zfcp_adapter_scsi_register_all(); /* release semaphore */ - ZFCP_UP(&zfcp_data.proc_sema); + up(&zfcp_data.proc_sema); MOD_DEC_USE_COUNT; out: @@ -4986,14 +4633,14 @@ (unsigned long) buffer); /* block access */ - ZFCP_DOWN(&zfcp_data.proc_sema); + down(&zfcp_data.proc_sema); zfcp_data.proc_buffer_map = ZFCP_KMALLOC( ZFCP_MAX_PROC_SIZE, GFP_KERNEL); if (!zfcp_data.proc_buffer_map) { /* release semaphore on memory shortage */ - ZFCP_UP(&zfcp_data.proc_sema); + up(&zfcp_data.proc_sema); ZFCP_LOG_NORMAL( "error: Not enough free memory for procfile" " output. No output will be given.\n"); @@ -5033,7 +4680,7 @@ if (zfcp_data.proc_buffer_map) { ZFCP_LOG_TRACE("Freeing zfcp_data.proc_buffer_map.\n"); ZFCP_KFREE(zfcp_data.proc_buffer_map, ZFCP_MAX_PROC_SIZE); - ZFCP_UP(&zfcp_data.proc_sema); + up(&zfcp_data.proc_sema); MOD_DEC_USE_COUNT; } @@ -5699,19 +5346,6 @@ "List lock owner PC: 0x%08lx\n", adapter->request_queue.queue_lock.lock, adapter->request_queue.queue_lock.owner_pc); -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - len += sprintf(pbuf->buf+len, - "current TOD: "); - len += zfcp_lock_meter_print_tod( - pbuf->buf+len); - len += sprintf(pbuf->buf+len,"\n"); - len += sprintf(pbuf->buf+len, - "time lock held: "); - len += zfcp_lock_meter_print_time( - &adapter->request_queue.lock_meter, - pbuf->buf+len); - len += sprintf(pbuf->buf+len,"\n"); -#endif len += sprintf(pbuf->buf+len,"\n"); len += sprintf(pbuf->buf+len, @@ -5819,6 +5453,23 @@ len += sprintf(pbuf->buf+len,"\n"); } +#ifdef ZFCP_STAT_QUEUES + len += sprintf(pbuf->buf + len, "\nOutbound queue full: 0x%08x ", + atomic_read(&adapter->outbound_queue_full)); + len += sprintf(pbuf->buf + len, "Outbound requests: 0x%08x\n\n", + atomic_read(&adapter->outbound_total)); +#endif +#ifdef ZFCP_STAT_REQSIZES + len += sprintf(pbuf->buf + len, "missed stats 0x%x\n", + atomic_read(&adapter->stat_errors)); + len = zfcp_statistics_print( + adapter, &adapter->read_req_head, + "rr", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); + len = zfcp_statistics_print( + adapter, &adapter->write_req_head, + "wr", pbuf->buf, len, ZFCP_MAX_PROC_SIZE); +#endif + ZFCP_LOG_TRACE("stored %d bytes in proc buffer\n", len); pbuf->len = len; @@ -5983,6 +5634,51 @@ zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_wait(adapter); user_len = strlen(buffer); + } else if (strncmp(ZFCP_STAT_RESET, buffer, strlen(ZFCP_STAT_RESET)) == 0) { +#ifdef ZFCP_STAT_REQSIZES + ZFCP_LOG_NORMAL( + "user triggered reset of all statisticss for the " + "adapter with devno 0x%04x\n", + adapter->devno); + atomic_compare_and_swap(1, 0, &adapter->stat_on); + zfcp_statistics_clear(adapter, &adapter->read_req_head); + zfcp_statistics_clear(adapter, &adapter->write_req_head); + atomic_set(&adapter->stat_errors, 0); + atomic_compare_and_swap(0, 1, &adapter->stat_on); +#endif + user_len = strlen(buffer); + } else if (strncmp(ZFCP_STAT_OFF, buffer, strlen(ZFCP_STAT_OFF)) == 0) { +#ifdef ZFCP_STAT_REQSIZES + if (atomic_compare_and_swap(1, 0, &adapter->stat_on)) { + ZFCP_LOG_NORMAL( + "warning: all statistics for the adapter " + "with devno 0x%04x already off\n ", + adapter->devno); + } else { + ZFCP_LOG_NORMAL( + "user triggered shutdown of all statistics for the " + "adapter with devno 0x%04x\n", + adapter->devno); + zfcp_statistics_clear(adapter, &adapter->read_req_head); + zfcp_statistics_clear(adapter, &adapter->write_req_head); + } +#endif + user_len = strlen(buffer); + } else if (strncmp(ZFCP_STAT_ON, buffer, strlen(ZFCP_STAT_ON)) == 0) { +#ifdef ZFCP_STAT_REQSIZES + if (atomic_compare_and_swap(0, 1, &adapter->stat_on)) { + ZFCP_LOG_NORMAL( + "warning: all statistics for the adapter " + "with devno 0x%04x already on\n ", + adapter->devno); + } else { + ZFCP_LOG_NORMAL( + "user triggered (re)start of all statistics for the " + "adapter with devno 0x%04x\n", + adapter->devno); + } +#endif + user_len = strlen(buffer); } else { ZFCP_LOG_INFO("error: unknown procfs command\n"); user_len = -EINVAL; @@ -6678,31 +6374,24 @@ ZFCP_LOG_TRACE("enter\n"); - ZFCP_READ_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + read_lock_irqsave(&zfcp_data.adapter_list_lock, flags); adapter = ZFCP_FIRST_ADAPTER; while (adapter) { - ZFCP_READ_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + read_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status)) { ZFCP_LOG_DEBUG( "adapter with devno 0x%04x needs " "to be registered with SCSI stack, " "waiting for erp to settle\n", adapter->devno); - debug_text_event(zfcp_data.spinlock_dbf,6,"wait"); - debug_event(zfcp_data.spinlock_dbf,6,&adapter->devno,sizeof(u32)); zfcp_erp_wait(adapter); - debug_text_event(zfcp_data.spinlock_dbf,6,"ewait"); - debug_event(zfcp_data.spinlock_dbf,6,&adapter->devno,sizeof(u32)); if (zfcp_adapter_scsi_register(adapter) == 0); retval++; - }else { - debug_text_event(zfcp_data.spinlock_dbf,6,"nowait"); - debug_event(zfcp_data.spinlock_dbf,6,&adapter->devno,sizeof(u32)); - } - ZFCP_READ_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + } + read_lock_irqsave(&zfcp_data.adapter_list_lock, flags); adapter = ZFCP_NEXT_ADAPTER(adapter); } - ZFCP_READ_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + read_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -6727,9 +6416,9 @@ (unsigned long) host, (unsigned long) dev_list); - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { - ZFCP_READ_LOCK(&port->unit_list_lock); + read_lock(&port->unit_list_lock); ZFCP_FOR_EACH_UNIT(port, unit) { ZFCP_LOG_DEBUG("Determinig if unit 0x%lx" " supports tagging\n", @@ -6755,9 +6444,9 @@ atomic_clear_mask(ZFCP_STATUS_UNIT_ASSUMETCQ, &unit->status); } } - ZFCP_READ_UNLOCK(&port->unit_list_lock); + read_unlock(&port->unit_list_lock); } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); ZFCP_LOG_TRACE("exit\n"); @@ -6870,7 +6559,7 @@ new_cmnd->host_scribble = NULL; - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->fake_list_lock,flags); + write_lock_irqsave(&adapter->fake_list_lock,flags); if(adapter->first_fake_cmnd==NULL) { adapter->first_fake_cmnd = new_cmnd; adapter->fake_scsi_timer.function = @@ -6887,7 +6576,7 @@ current_cmnd->host_scribble = (char *)new_cmnd; } atomic_inc(&adapter->fake_scsi_reqs_active); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->fake_list_lock,flags); + write_unlock_irqrestore(&adapter->fake_list_lock,flags); ZFCP_LOG_TRACE("exit\n"); @@ -6924,8 +6613,8 @@ * during completions and aborts taking place at the same time. * It needs to be the outer lock as in the eh_abort_handler. */ - ZFCP_READ_LOCK_IRQSAVE(&adapter->abort_lock, flags); - ZFCP_WRITE_LOCK(&adapter->fake_list_lock); + read_lock_irqsave(&adapter->abort_lock, flags); + write_lock(&adapter->fake_list_lock); if(adapter->first_fake_cmnd == NULL) { ZFCP_LOG_DEBUG("Processing of fake-queue called " "for an empty queue.\n"); @@ -6948,8 +6637,8 @@ /* Set list to empty */ adapter->first_fake_cmnd = NULL; } - ZFCP_WRITE_UNLOCK(&adapter->fake_list_lock); - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->abort_lock, flags); + write_unlock(&adapter->fake_list_lock); + read_unlock_irqrestore(&adapter->abort_lock, flags); ZFCP_LOG_TRACE("exit\n"); @@ -6970,7 +6659,6 @@ zfcp_adapter_t *adapter = unit->port->adapter; - zfcp_cmd_dbf_event_scsi("failing", adapter, scsi_cmnd); #ifdef ZFCP_DEBUG_REQUESTS debug_text_event(adapter->req_dbf, 2, "de_done:"); debug_event(adapter->req_dbf, 2, &scsi_cmnd, sizeof(unsigned long)); @@ -6978,6 +6666,9 @@ scsi_cmnd->SCp.ptr = (char*)0; scsi_cmnd->result = result; + + zfcp_cmd_dbf_event_scsi("failing", adapter, scsi_cmnd); + scsi_cmnd->scsi_done(scsi_cmnd); #undef ZFCP_LOG_AREA @@ -7028,6 +6719,7 @@ #endif /* ZFCP_DEBUG_REQUESTS */ scsi_cmnd->scsi_done = done; + scsi_cmnd->result = 0; if (!unit) { zfcp_scsi_command_fail(unit, scsi_cmnd, DID_NO_CONNECT << 16); @@ -7210,22 +6902,22 @@ id, lun); - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { if ((scsi_id_t)id != port->scsi_id) continue; - ZFCP_READ_LOCK(&port->unit_list_lock); + read_lock(&port->unit_list_lock); ZFCP_FOR_EACH_UNIT(port, unit) { if ((scsi_lun_t)lun == unit->scsi_lun) { ZFCP_LOG_TRACE("found unit\n"); break; } } - ZFCP_READ_UNLOCK(&port->unit_list_lock); + read_unlock(&port->unit_list_lock); if (unit) break; } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); ZFCP_LOG_TRACE("exit (0x%lx)\n", (unsigned long)unit); @@ -7261,7 +6953,7 @@ (unsigned long)adapter, (unsigned long)cmnd); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->fake_list_lock, flags); + write_lock_irqsave(&adapter->fake_list_lock, flags); current_cmnd=adapter->first_fake_cmnd; @@ -7296,7 +6988,7 @@ } while (current_cmnd->host_scribble != NULL); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->fake_list_lock, flags); + write_unlock_irqrestore(&adapter->fake_list_lock, flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -7385,14 +7077,14 @@ * put into the fsf_req queue. This makes implementation * easier. */ - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->abort_lock, flags); + write_lock_irqsave(&adapter->abort_lock, flags); /* * Check if we deal with a faked command, which we may just forget * about from now on */ if (zfcp_scsi_potential_abort_on_fake(adapter, scpnt)) { - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->abort_lock, flags); + write_unlock_irqrestore(&adapter->abort_lock, flags); #ifdef ZFCP_DEBUG_ABORTS strncpy(dbf_result, "##faked", ZFCP_ABORT_DBF_LENGTH); #endif @@ -7414,7 +7106,7 @@ * That's it. * Do not initiate abort but return SUCCESS. */ - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->abort_lock, flags); + write_unlock_irqrestore(&adapter->abort_lock, flags); retval = SUCCESS; #ifdef ZFCP_DEBUG_ABORTS strncpy(dbf_result, "##late1", ZFCP_ABORT_DBF_LENGTH); @@ -7451,7 +7143,7 @@ * On the other hand we do not need the lock anymore since * all critical accesses to scsi_req are done. */ - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->abort_lock, flags); + write_unlock_irqrestore(&adapter->abort_lock, flags); /* call FSF routine which does the abort */ new_fsf_req = zfcp_fsf_abort_fcp_command( (unsigned long)old_fsf_req, adapter, unit, 0); @@ -8163,96 +7855,6 @@ /* - * function: - * - * purpose: - * - * returns: - */ -static int zfcp_paranoia_qdio_queue( - zfcp_adapter_t *adapter, - int irq, - int queue_number, - int first_element, - int elements_processed, - int queue_flag) -{ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_QDIO - - int retval = -EINVAL; -#if 0 - int local_index; - int local_count; - int expected_first_element; - int max_expected_elements_processed; -#endif - - zfcp_qdio_queue_t *queue; - - ZFCP_LOG_TRACE( - "enter (adapter=0x%lx queue_number=%i " - "first_element=%i elements_processed=%i\n", - (unsigned long)adapter, - queue_number, - first_element, - elements_processed); - - if (!adapter) { - ZFCP_LOG_NORMAL( - "bug: Pointer to an adapter struct is a null " - "pointer\n"); - goto out; - } - - if (queue_number != 0) { - ZFCP_LOG_NORMAL( - "bug: A QDIO (data transfer mechanism) queue has the " - "wrong identification number (debug info %d).\n", - queue_number); - goto out; - } - - if ((first_element < 0) || (first_element >= QDIO_MAX_BUFFERS_PER_Q)) { - ZFCP_LOG_NORMAL( - "bug: A QDIO (data transfer mechanism) queue index is " - "out of bounds (debug info %d).\n", - first_element); - goto out; - } - - if (adapter->irq != irq) { - ZFCP_LOG_NORMAL( - "bug: Interrupt received on irq 0x%x, for the adapter " - "with irq 0x%x and devno 0x%04x\n", - irq, - adapter->irq, - adapter->devno); - goto out; - } - - if (queue_flag) { - queue = &adapter->response_queue; - ZFCP_LOG_TRACE("It's a response queue.\n"); - } - else { - queue = &adapter->request_queue; - ZFCP_LOG_TRACE("It's a request queue.\n"); - } - retval = 0; -out: - if(retval != 0) - ZFCP_LOG_NORMAL("exit %i\n", - retval); - ZFCP_LOG_TRACE("exit (%i)\n", retval); - - return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX -} - -/* * function: zfcp_qdio_handler_error_check * * purpose: called by the response handler to determine error condition @@ -8378,7 +7980,6 @@ zfcp_adapter_t *adapter; zfcp_qdio_queue_t *queue; - int retval; ZFCP_LOG_TRACE( "enter (irq=%i status=%i qdio_error=%i siga_error=%i " @@ -8403,25 +8004,6 @@ if (zfcp_qdio_handler_error_check(adapter, status, qdio_error, siga_error)) goto out; - /* - * we stored address of zfcp_adapter_t data structure - * associated with irq in int_parm - */ - - /* paranoia checks */ - ZFCP_PARANOIA { - retval = zfcp_paranoia_qdio_queue( - adapter, - irq, - queue_number, - first_element, - elements_processed, - 0); - - if (retval) - goto out; - } - /* cleanup all SBALs being program-owned now */ zfcp_zero_sbals( @@ -8499,23 +8081,6 @@ if (zfcp_qdio_handler_error_check(adapter, status, qdio_error, siga_error)) goto out; - /* - * we stored address of zfcp_adapter_t data structure - * associated with irq in int_parm - */ - /* paranoia check */ - ZFCP_PARANOIA { - retval = zfcp_paranoia_qdio_queue( - adapter, - irq, - queue_number, - first_element, - elements_processed, - 1); - if (retval) - goto out; - } - buffere = &(queue->buffer[first_element]->element[0]); ZFCP_LOG_DEBUG("first BUFFERE flags=0x%x \n", buffere->flags); @@ -8645,7 +8210,6 @@ zfcp_fsf_req_t *fsf_req; int retval = 0; - unsigned long flags; ZFCP_LOG_TRACE( "enter (sbale_addr=0x%lx)\n", @@ -8668,29 +8232,6 @@ /* valid request id and thus (hopefully :) valid fsf_req address */ fsf_req = (zfcp_fsf_req_t*)sbale_addr; - /* DEBUG: force an abort which is being hung than, usage of mod_parm dismisses pending fsf_req */ - -#if 0 - if (fsf_req->qtcb->prefix.rcd .. -eq_seq_no == 0x100) { - ZFCP_LOG_NORMAL("*******************force abort*****************\n"); - goto out; - } - - if (fsf_req->fsf_command == FSF_QTCB_ABORT_FCP_CMND) { - ZFCP_LOG_NORMAL("***********ignoring abort completion************\n"); - goto out; - } - if (fsf_req->fsf_command == FSF_QTCB_FCP_CMND) { - if((jiffies & 0xfff)<=0x40) { - printk( "*************************************" - "Debugging:Ignoring return of SCSI command" - "********************************\n"); - goto out; - } - } -#endif - ZFCP_PARANOIA { if ((fsf_req->common_magic != ZFCP_MAGIC) ||(fsf_req->specific_magic != ZFCP_MAGIC_FSFREQ)) { @@ -8715,14 +8256,6 @@ retval = -EINVAL; goto out; } - - ZFCP_READ_LOCK_IRQSAVE(&adapter->fsf_req_list_lock, flags); - retval = zfcp_paranoia_fsf_reqs(adapter, fsf_req); - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->fsf_req_list_lock, flags); - if (retval) { - retval = -EINVAL; - goto out; - } } #ifdef ZFCP_DEBUG_REQUESTS @@ -9788,7 +9321,7 @@ failed_req_create: out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -9809,11 +9342,11 @@ unsigned long flags; zfcp_port_t *port; - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + write_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT (adapter, port) if (port->d_id == (status_buffer->d_id & ZFCP_DID_MASK)) break; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + write_unlock_irqrestore(&adapter->port_list_lock, flags); if (!port) { ZFCP_LOG_NORMAL( @@ -9922,8 +9455,14 @@ case FSF_STATUS_READ_LINK_DOWN: ZFCP_LOG_FLAGS(1,"FSF_STATUS_READ_LINK_DOWN\n"); - /* Unneccessary, ignoring.... */ - + debug_text_event(adapter->erp_dbf, 0, "unsol_link_down:"); + ZFCP_LOG_INFO( + "Local link to adapter with devno 0x%04x is down\n", + adapter->devno); + atomic_set_mask( + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, + &adapter->status); + zfcp_erp_adapter_failed(adapter); zfcp_callback_do_link_down(adapter); break; @@ -10093,7 +9632,7 @@ break; } known=0; - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + write_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT (adapter, port) { if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) continue; @@ -10109,7 +9648,7 @@ zfcp_test_link(port); } } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + write_unlock_irqrestore(&adapter->port_list_lock, flags); #if 0 printk("known %d, no_notifications %d\n", known, no_notifications); @@ -10124,7 +9663,7 @@ if(reopen_unknown) { ZFCP_LOG_DEBUG("At least one unknown did " "underwent a state change.\n"); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + write_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT (adapter, port) { if (atomic_test_mask(ZFCP_STATUS_PORT_NAMESERVER, &port->status)) continue; @@ -10138,7 +9677,7 @@ ZFCP_STATUS_COMMON_ERP_FAILED); } } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + write_unlock_irqrestore(&adapter->port_list_lock, flags); } #undef ZFCP_LOG_AREA @@ -10159,12 +9698,12 @@ zfcp_in_els_dbf_event(adapter, "##plogi", status_buffer, 28); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + write_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { if (port->wwpn == (*(wwn_t *)&els_logi->nport_wwn)) break; } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + write_unlock_irqrestore(&adapter->port_list_lock, flags); if (!port) { ZFCP_LOG_DEBUG( @@ -10198,12 +9737,12 @@ zfcp_in_els_dbf_event(adapter, "##logo", status_buffer, 16); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + write_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { if (port->wwpn == els_logo->nport_wwpn) break; } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + write_unlock_irqrestore(&adapter->port_list_lock, flags); if (!port) { ZFCP_LOG_DEBUG( @@ -10403,7 +9942,7 @@ old_req_id); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_DEBUG("exit (0x%lx)\n", (unsigned long)fsf_req); @@ -10707,12 +10246,10 @@ int retval = 0; ZFCP_LOG_TRACE("enter (erp_action=0x%lx)\n", (unsigned long)erp_action); - ZFCP_PARANOIA { - if (!adapter->nameserver_port) { - ZFCP_LOG_NORMAL("bug: no nameserver available\n"); - retval = -EINVAL; - goto out; - } + if (!adapter->nameserver_port) { + ZFCP_LOG_NORMAL("bug: no nameserver available\n"); + retval = -EINVAL; + goto out; } retval = zfcp_gid_pn_buffers_alloc(&gid_pn, &adapter->pool.data_gid_pn); @@ -10859,12 +10396,11 @@ memset(ct_iu_resp, 0, sizeof(*ct_iu_resp)); ZFCP_LOG_TRACE("enter\n"); - ZFCP_PARANOIA { - if (!adapter->nameserver_port) { - ZFCP_LOG_NORMAL("bug: no nameserver available\n"); - ret = -EINVAL; - goto out; - } + + if (!adapter->nameserver_port) { + ZFCP_LOG_NORMAL("bug: no nameserver available\n"); + ret = -EINVAL; + goto out; } if ((ct_iu_req = @@ -11153,7 +10689,7 @@ } failed_req: out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); return retval; @@ -11701,7 +11237,7 @@ }; failed_req: out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); return retval; @@ -11877,12 +11413,6 @@ sbale->addr = addr; sbale->length = length; - -#ifdef ZFCP_STAT_REQSIZES - if (sbtype == SBAL_FLAGS0_TYPE_READ) - zfcp_statistics_inc(&zfcp_data.read_sg_head, length); - else zfcp_statistics_inc(&zfcp_data.write_sg_head, length); -#endif } @@ -11926,6 +11456,7 @@ struct scatterlist *sg_segment; int bytes, retval; volatile qdio_buffer_element_t *sbale; + zfcp_adapter_t *adapter; /* figure out last allowed SBAL */ zfcp_qdio_sbal_limit(fsf_req, max_sbals); @@ -11943,27 +11474,20 @@ sbtype, sg_segment->address, sg_segment->length); - if (retval < 0) { - bytes = retval; - goto out; - } else - bytes += retval; + if (retval < 0) + return retval; + bytes += retval; } /* assume that no other SBALEs are to follow in the same SBAL */ sbale = zfcp_qdio_sbale_curr(fsf_req); sbale->flags |= SBAL_FLAGS_LAST_ENTRY; -out: #ifdef ZFCP_STAT_REQSIZES - if (sbtype == SBAL_FLAGS0_TYPE_READ) { - zfcp_statistics_inc(&zfcp_data.read_sguse_head, sg_count); - zfcp_statistics_inc(&zfcp_data.read_req_head, bytes); - } else { - zfcp_statistics_inc(&zfcp_data.write_sguse_head, sg_count); - zfcp_statistics_inc(&zfcp_data.write_req_head, bytes); - } + adapter = fsf_req->adapter; + if (sbtype == SBAL_FLAGS0_TYPE_READ) + zfcp_statistics_inc(adapter, &adapter->read_req_head, bytes); + else zfcp_statistics_inc(adapter, &adapter->write_req_head, bytes); #endif - return bytes; } @@ -12075,7 +11599,7 @@ erp_action->adapter->devno); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&erp_action->adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -12086,6 +11610,92 @@ } +/** + * zfcp_fsf_exchange_config_evaluate + * @fsf_req: fsf_req which belongs to xchg config data request + * @xchg_ok: specifies if xchg config data was incomplete or complete (0/1) + * + * returns: -EIO on error, 0 otherwise + */ +static int +zfcp_fsf_exchange_config_evaluate(zfcp_fsf_req_t *fsf_req, int xchg_ok) +{ +#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF +#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_FSF + + fsf_qtcb_bottom_config_t *bottom; + zfcp_adapter_t *adapter = fsf_req->adapter; + + bottom = &fsf_req->qtcb->bottom.config; + ZFCP_LOG_DEBUG( + "low/high QTCB version 0x%x/0x%x of FSF\n", + bottom->low_qtcb_version, bottom->high_qtcb_version); + adapter->fsf_lic_version = bottom->lic_version; + adapter->supported_features = bottom->supported_features; + + if (xchg_ok) { + adapter->wwnn = bottom->nport_serv_param.wwnn; + adapter->wwpn = bottom->nport_serv_param.wwpn; + adapter->s_id = bottom->s_id & ZFCP_DID_MASK; + adapter->fc_topology = bottom->fc_topology; + adapter->fc_link_speed = bottom->fc_link_speed; + adapter->hydra_version = bottom->adapter_type; + } else { + adapter->wwnn = 0; + adapter->wwpn = 0; + adapter->s_id = 0; + adapter->fc_topology = 0; + adapter->fc_link_speed = 0; + adapter->hydra_version = 0; + } + + if (adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { + adapter->hardware_version = bottom->hardware_version; + memcpy(adapter->serial_number, bottom->serial_number, 17); + EBCASC(adapter->serial_number, sizeof(adapter->serial_number)); + } + + ZFCP_LOG_INFO( + "The adapter with devno=0x%04x reported " + "the following characteristics:\n" + "WWNN 0x%016Lx, WWPN 0x%016Lx, S_ID 0x%08x,\n" + "adapter version 0x%x, LIC version 0x%x, " + "FC link speed %d Gb/s\n", + adapter->devno, + (llui_t) adapter->wwnn, (llui_t) adapter->wwpn, + (unsigned int) adapter->s_id, + adapter->hydra_version, + adapter->fsf_lic_version, + adapter->fc_link_speed); + if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) { + ZFCP_LOG_NORMAL( + "error: the adapter with devno 0x%04x " + "only supports newer control block " + "versions in comparison to this device " + "driver (try updated device driver)\n", + adapter->devno); + debug_text_event(adapter->erp_dbf, 0, "low_qtcb_ver"); + zfcp_erp_adapter_shutdown(adapter, 0); + return -EIO; + } + if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) { + ZFCP_LOG_NORMAL( + "error: the adapter with devno 0x%04x " + "only supports older control block " + "versions than this device driver uses" + "(consider a microcode upgrade)\n", + adapter->devno); + debug_text_event(adapter->erp_dbf, 0, "high_qtcb_ver"); + zfcp_erp_adapter_shutdown(adapter, 0); + return -EIO; + } + return 0; + +#undef ZFCP_LOG_AREA +#undef ZFCP_LOG_AREA_PREFIX +} + + /* * function: zfcp_fsf_exchange_config_data_handler * @@ -12107,78 +11717,17 @@ "enter (fsf_req=0x%lx)\n", (unsigned long)fsf_req); -#if 0 - /* DEBUGGING */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, - &(fsf_req->adapter->status)); -#endif if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { /* don't set any value, stay with the old (unitialized) ones */ goto skip_fsfstatus; } - /* evaluate FSF status in QTCB */ switch (fsf_req->qtcb->header.fsf_status) { case FSF_GOOD : ZFCP_LOG_FLAGS(2,"FSF_GOOD\n"); - bottom = &fsf_req->qtcb->bottom.config; - /* only log QTCB versions for now */ - ZFCP_LOG_DEBUG("low QTCB version 0x%x of FSF, " - "high QTCB version 0x%x of FSF, \n", - bottom->low_qtcb_version, - bottom->high_qtcb_version); - adapter->wwnn = bottom->nport_serv_param.wwnn; - adapter->wwpn = bottom->nport_serv_param.wwpn; - adapter->s_id = bottom->s_id & ZFCP_DID_MASK; - adapter->hydra_version = bottom->adapter_type; - adapter->fsf_lic_version = bottom->lic_version; - adapter->fc_topology = bottom->fc_topology; - adapter->fc_link_speed = bottom->fc_link_speed; - adapter->supported_features = bottom->supported_features; - if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){ - adapter->hardware_version = bottom->hardware_version; - /* copy just first 17 bytes */ - memcpy(adapter->serial_number, - bottom->serial_number, 17); - EBCASC(adapter->serial_number, - sizeof(adapter->serial_number)); - } - ZFCP_LOG_INFO( - "The adapter with devno 0x%04x reported " - "the following characteristics:\n" - "WWNN 0x%016Lx, WWPN 0x%016Lx, S_ID 0x%06x,\n" - "adapter version 0x%x, LIC version 0x%x, FC link speed %d Gb/s\n", - adapter->devno, - (llui_t)adapter->wwnn, - (llui_t)adapter->wwpn, - adapter->s_id, - adapter->hydra_version, - adapter->fsf_lic_version, - adapter->fc_link_speed); - if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) { - ZFCP_LOG_NORMAL( - "error: the adapter with devno 0x%04x " - "only supports newer control block versions " - "in comparison to this device driver " - "(try updated device driver)\n", - adapter->devno); - debug_text_event(fsf_req->adapter->erp_dbf,0,"low_qtcb_ver"); - zfcp_erp_adapter_shutdown(adapter, 0); + if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) goto skip_fsfstatus; - } - if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) { - ZFCP_LOG_NORMAL( - "error: the adapter with devno 0x%04x " - "only supports older control block versions " - "than this device driver uses" - "(consider a microcode upgrade)\n", - adapter->devno); - debug_text_event(fsf_req->adapter->erp_dbf,0,"high_qtcb_ver"); - zfcp_erp_adapter_shutdown(adapter, 0); - goto skip_fsfstatus; - } switch (adapter->fc_topology) { case FSF_TOPO_P2P: ZFCP_LOG_FLAGS(1,"FSF_TOPO_P2P\n"); @@ -12222,7 +11771,8 @@ zfcp_erp_adapter_shutdown(adapter, 0); goto skip_fsfstatus; } - if(bottom->max_qtcb_size < sizeof(fsf_qtcb_t)) { + bottom = &fsf_req->qtcb->bottom.config; + if (bottom->max_qtcb_size < sizeof(fsf_qtcb_t)) { ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) " "allowed by the adapter with devno " "0x%04x is lower than the minimum " @@ -12243,6 +11793,21 @@ break; + case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: + debug_text_event(adapter->erp_dbf, 0, "xchg-inco"); + + if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) + goto skip_fsfstatus; + + ZFCP_LOG_INFO( + "Local link to adapter with devno 0x%04x is down\n", + adapter->devno); + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, + &adapter->status); + zfcp_erp_adapter_failed(adapter); + break; + default: /* retval is -EIO by default */ debug_text_event(fsf_req->adapter->erp_dbf,0,"fsf-stat-ng"); @@ -12290,7 +11855,7 @@ "exchange port data request for" "the adapter with devno 0x%4.4x.\n", adapter->devno); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); goto out; } @@ -12314,7 +11879,7 @@ (unsigned long)fsf_req); } fsf_req = NULL; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); goto out; } @@ -12323,7 +11888,7 @@ "(adapter devno=0x%x)\n", adapter->devno); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); /* FIXME: could we wait interruptible here ? */ @@ -12458,7 +12023,7 @@ (llui_t)erp_action->port->wwpn); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&erp_action->adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -12748,7 +12313,7 @@ (llui_t)erp_action->port->wwpn); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&erp_action->adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -12961,7 +12526,7 @@ (llui_t)erp_action->port->wwpn); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&erp_action->adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -13103,12 +12668,12 @@ */ atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, unit) { atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); } - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); retval = 0; break; @@ -13222,7 +12787,7 @@ (llui_t)erp_action->unit->fcp_lun); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&erp_action->adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -13362,8 +12927,8 @@ "connected to the adapter " "with devno 0x%04x " "is denied (%s rule %d)\n", - unit->fcp_lun, - unit->port->wwpn, + (llui_t)unit->fcp_lun, + (llui_t)unit->port->wwpn, adapter->devno, zfcp_act_subtable_type[subtable], rule); @@ -13545,7 +13110,7 @@ (llui_t)erp_action->unit->fcp_lun); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&erp_action->adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -13835,7 +13400,7 @@ } out: - ZFCP_WRITE_UNLOCK_IRQRESTORE( + write_unlock_irqrestore( &adapter->request_queue.queue_lock, lock_flags); no_act_support: @@ -14443,7 +14008,7 @@ success: failed_req_create: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (%d)\n", retval); @@ -14573,7 +14138,7 @@ tm_flags); out: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); ZFCP_LOG_TRACE("exit (0x%lx)\n", (unsigned long)fsf_req); @@ -14972,7 +14537,7 @@ "enter (fsf_req=0x%lx)\n", (unsigned long)fsf_req); - ZFCP_READ_LOCK_IRQSAVE(&fsf_req->adapter->abort_lock, flags); + read_lock_irqsave(&fsf_req->adapter->abort_lock, flags); scpnt = fsf_req->data.send_fcp_command_task.scsi_cmnd; if (!scpnt) { ZFCP_LOG_DEBUG("Command with fsf_req 0x%lx is not associated to " @@ -14981,8 +14546,6 @@ goto out; } - scpnt->result = 0; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTED) { /* FIXME: (design) mid-layer should handle DID_ABORT like * DID_SOFT_ERROR by retrying the request for devices @@ -15315,7 +14878,7 @@ * Note: scsi_done must not block! */ out: - ZFCP_READ_UNLOCK_IRQRESTORE(&fsf_req->adapter->abort_lock, flags); + read_unlock_irqrestore(&fsf_req->adapter->abort_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -15496,17 +15059,10 @@ #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF #define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_FSF -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - unsigned long long time; - time = get_clock(); -#endif - ZFCP_WRITE_LOCK_IRQSAVE(&queue->queue_lock, *flags); -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - zfcp_lock_meter_add(&queue->lock_meter, time); -#endif + write_lock_irqsave(&queue->queue_lock, *flags); if (atomic_read(&queue->free_count) >= needed) return 1; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&queue->queue_lock, *flags); + write_unlock_irqrestore(&queue->queue_lock, *flags); return 0; #undef ZFCP_LOG_AREA @@ -15595,10 +15151,6 @@ zfcp_qdio_queue_t *req_queue = &adapter->request_queue; volatile qdio_buffer_element_t *sbale; -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - unsigned long long time; -#endif - ZFCP_LOG_TRACE("enter (adapter=0x%lx fsf_cmd=0x%x *lock_flags=0x%lx " "req_flags=0x%x)\n", (unsigned long)adapter, fsf_cmd, *lock_flags, req_flags); @@ -15657,7 +15209,7 @@ failed_sbals: #ifdef ZFCP_STAT_QUEUES - atomic_inc(&zfcp_data.outbound_queue_full); + atomic_inc(&adapter->outbound_queue_full); #endif /* dequeue new FSF request previously enqueued */ zfcp_fsf_req_free(fsf_req); @@ -15665,13 +15217,7 @@ failed_fsf_req: //failed_running: -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - time = get_clock(); -#endif - ZFCP_WRITE_LOCK_IRQSAVE(&req_queue->queue_lock, *lock_flags); -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - zfcp_lock_meter_add(&req_queue->lock_meter, time); -#endif + write_lock_irqsave(&req_queue->queue_lock, *lock_flags); success: *fsf_req_p = fsf_req; @@ -15794,10 +15340,10 @@ inc_seq_no = 0; /* put allocated FSF request at list tail */ - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->fsf_req_list_lock, flags); + write_lock_irqsave(&adapter->fsf_req_list_lock, flags); list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->fsf_req_list_lock, flags); + write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); /* figure out expiration time of timeout and start timeout */ if (timer) { @@ -15846,9 +15392,9 @@ /* FIXME(potential race): timer might be expired (absolutely unlikely) */ if (timer) del_timer_sync(timer); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->fsf_req_list_lock, flags); + write_lock_irqsave(&adapter->fsf_req_list_lock, flags); list_del(&fsf_req->list); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->fsf_req_list_lock, flags); + write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); /* * adjust the number of free SBALs in request queue as well as * position of first one @@ -15902,7 +15448,7 @@ /* count FSF requests pending */ atomic_inc(&adapter->fsf_reqs_active); #ifdef ZFCP_STAT_QUEUES - atomic_inc(&zfcp_data.outbound_total); + atomic_inc(&adapter->outbound_total); #endif } @@ -15935,9 +15481,9 @@ ZFCP_LOG_TRACE("enter (fsf_req=0x%lx)\n", (unsigned long)fsf_req); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->fsf_req_list_lock, flags); + write_lock_irqsave(&adapter->fsf_req_list_lock, flags); list_del(&fsf_req->list); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->fsf_req_list_lock, flags); + write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); retval = zfcp_fsf_req_free(fsf_req); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -16328,7 +15874,7 @@ (unsigned long)rec); /* check for adapter */ - ZFCP_WRITE_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + write_lock_irqsave(&zfcp_data.adapter_list_lock, flags); ZFCP_FOR_EACH_ADAPTER(adapter) { if (adapter->devno == rec->devno) break; @@ -16343,7 +15889,7 @@ } /* check for remote port */ - ZFCP_WRITE_LOCK(&adapter->port_list_lock); + write_lock(&adapter->port_list_lock); ZFCP_FOR_EACH_PORT(adapter, port) { if (port->scsi_id == rec->scsi_id) break; @@ -16367,7 +15913,7 @@ } /* check for logical unit */ - ZFCP_WRITE_LOCK(&port->unit_list_lock); + write_lock(&port->unit_list_lock); ZFCP_FOR_EACH_UNIT(port, unit) { if (unit->scsi_lun == rec->scsi_lun) break; @@ -16418,11 +15964,11 @@ retval = 0; unlock_unit: - ZFCP_WRITE_UNLOCK(&port->unit_list_lock); + write_unlock(&port->unit_list_lock); unlock_port: - ZFCP_WRITE_UNLOCK(&adapter->port_list_lock); + write_unlock(&adapter->port_list_lock); unlock_adapter: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + write_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); return retval; @@ -16515,9 +16061,9 @@ (unsigned long)adapter, clear_mask); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -17116,21 +16662,12 @@ (unsigned long)port, clear_mask); - ZFCP_PARANOIA { - if (!adapter) { - ZFCP_LOG_DEBUG("bug: No adapter specified (null pointer)\n"); - retval = -EINVAL; - goto out; - } - } - - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); -out: return retval; #undef ZFCP_LOG_AREA @@ -17229,21 +16766,12 @@ (unsigned long)port, clear_mask); - ZFCP_PARANOIA { - if (!adapter) { - ZFCP_LOG_DEBUG("bug: No adapter specified (null pointer)\n"); - retval = -EINVAL; - goto out; - } - } - - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); retval = zfcp_erp_port_reopen_internal(port, clear_mask); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); -out: return retval; #undef ZFCP_LOG_AREA @@ -17338,34 +16866,19 @@ int retval; unsigned long flags; - zfcp_adapter_t *adapter; + zfcp_adapter_t *adapter = unit->port->adapter; ZFCP_LOG_TRACE( "enter (unit=0x%lx clear_mask=0x%x)\n", (unsigned long)unit, clear_mask); - ZFCP_PARANOIA { - if (!unit->port) { - ZFCP_LOG_DEBUG("bug: No port specified (null pointer)\n"); - retval = -EINVAL; - goto out; - } - if (!unit->port->adapter) { - ZFCP_LOG_DEBUG("bug: No adapter specified (null pointer)\n"); - retval = -EINVAL; - goto out; - } - } - adapter = unit->port->adapter; - - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); retval = zfcp_erp_unit_reopen_internal(unit, clear_mask); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); -out: return retval; #undef ZFCP_LOG_AREA @@ -17605,7 +17118,7 @@ ZFCP_LOG_DEBUG( "Waking erp_thread of adapter with devno 0x%04x\n", adapter->devno); - ZFCP_UP(&adapter->erp_ready_sem); + up(&adapter->erp_ready_sem); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -17745,7 +17258,7 @@ "enter (fsf_req=0x%lx)\n", (unsigned long)fsf_req); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); erp_action = fsf_req->erp_action; if (erp_action != 0) { debug_text_event(adapter->erp_dbf, 5, "a_frh_norm"); @@ -17759,7 +17272,7 @@ /* timeout (?) or dismiss ran - nothing to do */ debug_text_event(adapter->erp_dbf, 3, "a_frh_tfin"); } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit\n"); @@ -17788,7 +17301,7 @@ ZFCP_LOG_TRACE("enter (data=0x%lx)\n", data); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); if (zfcp_erp_action_exists(erp_action) != ZFCP_ERP_ACTION_RUNNING) { /* action is ready or gone - nothing to do */ debug_text_event(adapter->erp_dbf, 3, "a_mwh_nrun"); @@ -17799,7 +17312,7 @@ debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof(int)); zfcp_erp_action_ready(erp_action); unlock: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit\n"); @@ -17832,7 +17345,7 @@ ZFCP_LOG_TRACE("enter (data=0x%lx)\n", data); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); if (zfcp_erp_action_exists(erp_action) != ZFCP_ERP_ACTION_RUNNING) { /* action is ready or gone - nothing to do */ debug_text_event(adapter->erp_dbf, 3, "a_th_nrun"); @@ -17876,7 +17389,7 @@ } unlock: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit\n"); return; @@ -18083,7 +17596,7 @@ "Killing erp_thread for the adapter with devno 0x%04x\n", adapter->devno); atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); - ZFCP_UP(&adapter->erp_ready_sem); + up(&adapter->erp_ready_sem); wait_event( adapter->erp_thread_wqh, !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status)); @@ -18147,9 +17660,9 @@ /* (nearly) infinite loop */ for (;;) { /* sleep as long as there is no action in 'ready' queue */ - ZFCP_DOWN_INTERRUPTIBLE(&adapter->erp_ready_sem); + down_interruptible(&adapter->erp_ready_sem); #ifdef ZFCP_ERP_DEBUG_SINGLE_STEP - ZFCP_DOWN(&adapter->erp_continue_sem); + down(&adapter->erp_continue_sem); #endif // ZFCP_ERP_DEBUG_SINGLE_STEP ZFCP_LOG_TRACE( "erp thread woken on adapter with devno 0x%04x\n", @@ -18162,25 +17675,22 @@ "Recognized kill flag for the erp_thread of " "the adapter with devno 0x%04x\n", adapter->devno); - ZFCP_PARANOIA { - ZFCP_READ_LOCK_IRQSAVE(&adapter->erp_lock, flags); - retval = !list_empty(&adapter->erp_ready_head) || - !list_empty(&adapter->erp_running_head); - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); - if (retval) { - debug_text_exception(adapter->erp_dbf, 1, "a_th_bkill"); - ZFCP_LOG_NORMAL( - "bug: error recovery thread is " - "shutting down although there are " - "error recovery actions pending at " - "adapter with devno 0x%04x\n", - adapter->devno); - /* don't exit erp to avoid potential system crash */ - } else break; + read_lock_irqsave(&adapter->erp_lock, flags); + retval = !list_empty(&adapter->erp_ready_head) || + !list_empty(&adapter->erp_running_head); + read_unlock_irqrestore(&adapter->erp_lock, flags); + if (retval) { + debug_text_exception(adapter->erp_dbf, 1, "a_th_bkill"); + ZFCP_LOG_NORMAL( + "bug: error recovery thread is " + "shutting down although there are " + "error recovery actions pending at " + "adapter with devno 0x%04x\n", + adapter->devno); + /* don't exit erp to avoid potential system crash */ } else break; } - /* paranoia check */ ZFCP_PARANOIA { /* there should be something in 'ready' queue */ /* @@ -18189,9 +17699,9 @@ * modification when another action is put to this * queue (only list tail won't be modified then) */ - ZFCP_READ_LOCK_IRQSAVE(&adapter->erp_lock, flags); + read_lock_irqsave(&adapter->erp_lock, flags); retval = list_empty(&adapter->erp_ready_head); - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + read_unlock_irqrestore(&adapter->erp_lock, flags); if (retval) { debug_text_exception(adapter->erp_dbf, 1, "a_th_empt"); ZFCP_LOG_NORMAL( @@ -18265,7 +17775,7 @@ (unsigned long)erp_action); /* don't process dismissed erp action, just dequeue it */ - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); retval = zfcp_erp_strategy_check_dismissed(erp_action); /* leave if this action is gone */ if (retval == ZFCP_ERP_DISMISSED) { @@ -18279,7 +17789,7 @@ * action to the 'running' queue and back) */ zfcp_erp_action_to_running(erp_action); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); /* no lock to allow for blocking operations (kmalloc, qdio, ...) */ @@ -18310,7 +17820,7 @@ * actions to finish this before we decide about * necessary steps to be taken here further */ - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); /* still not dismissed? */ temp_retval = zfcp_erp_strategy_check_dismissed(erp_action); @@ -18350,7 +17860,7 @@ action, adapter, port, unit, retval); unlock: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); out: /* @@ -19019,7 +18529,7 @@ ZFCP_LOG_TRACE("enter\n"); - ZFCP_READ_LOCK_IRQSAVE(&adapter->erp_lock, flags); + read_lock_irqsave(&adapter->erp_lock, flags); if (list_empty(&adapter->erp_ready_head) && list_empty(&adapter->erp_running_head)) { debug_text_event(adapter->erp_dbf, 4, "a_cq_wake"); @@ -19027,7 +18537,7 @@ &adapter->status); wake_up(&adapter->erp_done_wqh); } else debug_text_event(adapter->erp_dbf, 5, "a_cq_notempty"); - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + read_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -19104,13 +18614,13 @@ if(!common_mask) goto out; /* Deal with all underlying devices, only pass common_mask */ - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { zfcp_erp_modify_port_status(port, common_mask, set_or_clear); } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); out: ZFCP_LOG_TRACE("exit\n"); @@ -19157,13 +18667,13 @@ if(!common_mask) goto out; /* Modify status of all underlying devices, only pass common mask */ - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, unit) { zfcp_erp_modify_unit_status(unit, common_mask, set_or_clear); } - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); out: ZFCP_LOG_TRACE("exit\n"); @@ -19233,21 +18743,12 @@ (unsigned long)adapter, clear_mask); - ZFCP_PARANOIA { - if (!adapter) { - ZFCP_LOG_DEBUG("bug: No adapter specified (null pointer)\n"); - retval = -EINVAL; - goto out; - } - } - - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask); - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); -out: return retval; #undef ZFCP_LOG_AREA @@ -19278,12 +18779,12 @@ (unsigned long)adapter, clear_mask); - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { if (!atomic_test_mask(ZFCP_STATUS_PORT_NAMESERVER, &port->status)) zfcp_erp_port_reopen_internal(port, clear_mask); } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -19317,10 +18818,10 @@ (unsigned long)port, clear_mask); - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, unit) zfcp_erp_unit_reopen_internal(unit, clear_mask); - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -19775,9 +19276,6 @@ zfcp_adapter_t *adapter = erp_action->adapter; #if 0 unsigned long flags; -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - unsigned long long time; -#endif #endif ZFCP_LOG_TRACE("enter\n"); @@ -19819,13 +19317,7 @@ * exchange config data...that should be fine, however */ #if 0 -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - time = get_clock(); -#endif - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->request_queue.queue_lock, flags); -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - zfcp_lock_meter_add(&adapter->request_queue.lock_meter, time); -#endif + write_lock_irqsave(&adapter->request_queue.queue_lock, flags); #endif //0 if (qdio_cleanup(adapter->irq, QDIO_FLAG_CLEANUP_USING_CLEAR) != 0) { @@ -19862,7 +19354,7 @@ atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); #if 0 - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->request_queue.queue_lock, flags); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, flags); #endif out: ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -19963,7 +19455,7 @@ * _must_ be the one belonging to the 'exchange config * data' request. */ - ZFCP_DOWN_INTERRUPTIBLE(&adapter->erp_ready_sem); + down_interruptible(&adapter->erp_ready_sem); if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { ZFCP_LOG_INFO( "error: Exchange of configuration data between " @@ -20455,7 +19947,7 @@ ZFCP_LOG_TRACE("enter\n"); - ZFCP_WRITE_LOCK_IRQSAVE(&adapter->erp_lock, flags); + write_lock_irqsave(&adapter->erp_lock, flags); list_for_each_safe(entry, temp_entry, &adapter->erp_running_head) { tmp_erp_action = list_entry(entry, zfcp_erp_action_t, list); debug_text_event(adapter->erp_dbf, 3, "p_pstnsw_n"); @@ -20470,7 +19962,7 @@ zfcp_erp_action_ready(tmp_erp_action); } } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&adapter->erp_lock, flags); + write_unlock_irqrestore(&adapter->erp_lock, flags); ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -21142,7 +20634,7 @@ ZFCP_LOG_DEBUG( "waking erp_thread of the adapter with devno=0x%04x\n", adapter->devno); - ZFCP_UP(&adapter->erp_ready_sem); + up(&adapter->erp_ready_sem); retval = 0; out: @@ -21227,11 +20719,11 @@ zfcp_erp_action_dismiss(&adapter->erp_action); else { /* have a deeper look */ - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { zfcp_erp_action_dismiss_port(port); } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); } ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -21269,13 +20761,13 @@ zfcp_erp_action_dismiss(&port->erp_action); else { /* have a deeper look */ - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, unit) { if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) { zfcp_erp_action_dismiss(&unit->erp_action); } } - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); } ZFCP_LOG_TRACE("exit (%i)\n", retval); @@ -21380,300 +20872,140 @@ #ifdef ZFCP_STAT_REQSIZES -/* - * function: - * - * purpose: - * - * returns: - */ -static int zfcp_statistics_clear(struct list_head *head) +static int zfcp_statistics_clear( + zfcp_adapter_t *adapter, + struct list_head *head) { -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - int retval = 0; unsigned long flags; struct list_head *entry, *next_entry; zfcp_statistics_t *stat; - ZFCP_LOG_TRACE("enter\n"); - - ZFCP_WRITE_LOCK_IRQSAVE(&zfcp_data.stat_lock, flags); + write_lock_irqsave(&adapter->stat_lock, flags); list_for_each_safe(entry, next_entry, head) { stat = list_entry(entry, zfcp_statistics_t, list); list_del(entry); kfree(stat); } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&zfcp_data.stat_lock, flags); - - ZFCP_LOG_TRACE("exit (%i)\n", retval); + write_unlock_irqrestore(&adapter->stat_lock, flags); return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX } -/* - * function: - * - * purpose: - * - * returns: - */ -static int zfcp_statistics_new( +static inline void zfcp_statistics_new( + zfcp_adapter_t *adapter, struct list_head *head, u32 num) { -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - - int retval = 0; zfcp_statistics_t *stat; - ZFCP_LOG_TRACE("enter\n"); - stat = ZFCP_KMALLOC(sizeof(zfcp_statistics_t), GFP_ATOMIC); if (stat) { stat->num = num; - stat->occurrence = 1; + stat->hits = 1; list_add_tail(&stat->list, head); - } else zfcp_data.stat_errors++; - - ZFCP_LOG_TRACE("exit (%i)\n", retval); + } else atomic_inc(&adapter->stat_errors); +} - return retval; +/** + * list_for_some_prev - iterate over a list backwards + * starting somewhere in the middle + * of the list + * @pos: the &list_t to use as a loop counter. + * @middle: the &list_t pointing to the antecessor to start at + * @head: the head for your list. + */ +#define list_for_some_prev(pos, middle, head) \ + for (pos = (middle)->prev, prefetch(pos->prev); pos != (head); \ + pos = pos->prev, prefetch(pos->prev)) + +/* + * Sort list if necessary to find frequently used entries quicker. + * Since counters are only increased by one, sorting can be implemented + * in a quite efficient way. It usually comprimises swapping positions + * of the given entry with its antecessor, if at all. In rare cases + * (= if there is a series of antecessors with identical counter values + * which are in turn less than the value hold by the current entry) + * searching for the position where we want to move the current entry to + * takes more than one hop back through the list. As to the overall + * performance of our statistics this is not a big deal. + * As a side-effect, we provide statistics sorted by hits to the user. + */ +static inline void zfcp_statistics_sort( + struct list_head *head, + struct list_head *entry, + zfcp_statistics_t *stat) +{ + zfcp_statistics_t *stat_sort = NULL; + struct list_head *entry_sort = NULL; -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX + list_for_some_prev(entry_sort, entry, head) { + stat_sort = list_entry(entry_sort, zfcp_statistics_t, list); + if (stat_sort->hits >= stat->hits) + break; + } + if (stat_sort && + entry->prev != entry_sort) + list_move(entry, entry_sort); } -static int zfcp_statistics_inc( +static void zfcp_statistics_inc( + zfcp_adapter_t *adapter, struct list_head *head, u32 num) { -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - - int retval = 0; unsigned long flags; zfcp_statistics_t *stat; struct list_head *entry; - ZFCP_LOG_TRACE("enter\n"); + if (atomic_read(&adapter->stat_on) == 0) + return; - ZFCP_WRITE_LOCK_IRQSAVE(&zfcp_data.stat_lock, flags); + write_lock_irqsave(&adapter->stat_lock, flags); list_for_each(entry, head) { stat = list_entry(entry, zfcp_statistics_t, list); if (stat->num == num) { - stat->occurrence++; + stat->hits++; + zfcp_statistics_sort(head, entry, stat); goto unlock; } } - /* occurrence must be initialized to 1 */ - zfcp_statistics_new(head, num); + /* hits is initialized to 1 */ + zfcp_statistics_new(adapter, head, num); unlock: - ZFCP_WRITE_UNLOCK_IRQRESTORE(&zfcp_data.stat_lock, flags); - - ZFCP_LOG_TRACE("exit (%i)\n", retval); - - return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX + write_unlock_irqrestore(&adapter->stat_lock, flags); } static int zfcp_statistics_print( + zfcp_adapter_t *adapter, struct list_head *head, char *prefix, char *buf, int len, int max) { -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - unsigned long flags; zfcp_statistics_t *stat; struct list_head *entry; - ZFCP_LOG_TRACE("enter\n"); - - ZFCP_WRITE_LOCK_IRQSAVE(&zfcp_data.stat_lock, flags); + write_lock_irqsave(&adapter->stat_lock, flags); list_for_each(entry, head) { if (len > max - 26) break; stat = list_entry(entry, zfcp_statistics_t, list); - len += sprintf(buf + len, "%s 0x%08x: 0x%08x\n", prefix, stat->num, stat->occurrence); + len += sprintf(buf + len, "%s 0x%08x: 0x%08x\n", + prefix, stat->num, stat->hits); } - ZFCP_WRITE_UNLOCK_IRQRESTORE(&zfcp_data.stat_lock, flags); - - ZFCP_LOG_TRACE("exit (%i)\n", len); + write_unlock_irqrestore(&adapter->stat_lock, flags); return len; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX -} - - -/* - * function: - * - * purpose: - * - * returns: - */ -static int zfcp_statistics_init_all(void) -{ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - - int retval = 0; - - ZFCP_LOG_TRACE("enter\n"); - - rwlock_init(&zfcp_data.stat_lock); - INIT_LIST_HEAD(&zfcp_data.read_req_head); - INIT_LIST_HEAD(&zfcp_data.write_req_head); - INIT_LIST_HEAD(&zfcp_data.read_sg_head); - INIT_LIST_HEAD(&zfcp_data.write_sg_head); - INIT_LIST_HEAD(&zfcp_data.read_sguse_head); - INIT_LIST_HEAD(&zfcp_data.write_sguse_head); - - ZFCP_LOG_TRACE("exit (%i)\n", retval); - - return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX -} - - -/* - * function: - * - * purpose: - * - * returns: - */ -static int zfcp_statistics_clear_all(void) -{ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -#define ZFCP_LOG_AREA_PREFIX ZFCP_LOG_AREA_PREFIX_OTHER - - int retval = 0; - - ZFCP_LOG_TRACE("enter\n"); - - zfcp_statistics_clear(&zfcp_data.read_req_head); - zfcp_statistics_clear(&zfcp_data.write_req_head); - zfcp_statistics_clear(&zfcp_data.read_sg_head); - zfcp_statistics_clear(&zfcp_data.write_sg_head); - zfcp_statistics_clear(&zfcp_data.read_sguse_head); - zfcp_statistics_clear(&zfcp_data.write_sguse_head); - - ZFCP_LOG_TRACE("exit (%i)\n", retval); - - return retval; - -#undef ZFCP_LOG_AREA -#undef ZFCP_LOG_AREA_PREFIX } #endif // ZFCP_STAT_REQSIZES - -#ifdef ZFCP_STAT_REQ_QUEUE_LOCK - -static inline unsigned long long zfcp_lock_meter_init( - zfcp_lock_meter_t *meter) -{ - unsigned long flags; - - rwlock_init(&meter->lock); - ZFCP_WRITE_LOCK_IRQSAVE(&meter->lock, flags); - meter->time = 0; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&meter->lock, flags); - - return 0; -} - -static inline unsigned long long zfcp_lock_meter_add( - zfcp_lock_meter_t *meter, - unsigned long long time) -{ - unsigned long flags; - - time = get_clock() - time; - ZFCP_WRITE_LOCK_IRQSAVE(&meter->lock, flags); - meter->time += time; - ZFCP_WRITE_UNLOCK_IRQRESTORE(&meter->lock, flags); - - return time; -} - -extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); - -/* According to Martin Schwidefsky this is not not recommended */ -#if 0 -static inline unsigned long long zfcp_adjust_tod( - unsigned long long time) -{ - time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); - return time; -} - -static inline int zfcp_lock_meter_print( - zfcp_lock_meter_t *meter, - unsigned long long *time_ptr, - char *buf) -{ - unsigned long flags; - unsigned long long time; - struct timeval tval; - int len; - - ZFCP_READ_LOCK_IRQSAVE(&meter->lock, flags); - time = *time_ptr; - ZFCP_READ_UNLOCK_IRQRESTORE(&meter->lock, flags); - time = zfcp_adjust_tod(time); - tod_to_timeval(time, &tval); - len = sprintf(buf, "%011lu:%06lu", tval.tv_sec, tval.tv_usec); - - return len; -} -#endif - -static inline int zfcp_lock_meter_print_tod( - char *buf) -{ - return sprintf(buf, "%Lu", get_clock()); -} - -static inline int zfcp_lock_meter_print_time( - zfcp_lock_meter_t *meter, - char *buf) -{ - unsigned long flags; - unsigned long long time; - int len; - - ZFCP_READ_LOCK_IRQSAVE(&meter->lock, flags); - time = meter->time; - ZFCP_READ_UNLOCK_IRQRESTORE(&meter->lock, flags); - len = sprintf(buf, "%Lu", time); - - return len; -} - -#endif // ZFCP_STAT_REQ_QUEUE_LOCK - - /* * function: zfcp_cfdc_dev_ioctl * --- linux-2.4.26/drivers/s390/scsi/zfcp_zh.c.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/drivers/s390/scsi/zfcp_zh.c 2004-09-18 19:02:14.000000000 -0400 @@ -1,5 +1,5 @@ /* - * $Id: zfcp_zh.c,v 1.3.2.1 2004/01/26 17:26:34 mschwide Exp $ + * $Id: zfcp_zh.c,v 1.3.2.2 2004/06/08 10:10:29 mpeschke Exp $ * * Module providing an interface for HBA API (FC-HBA) implementation * to the zfcp driver. @@ -173,14 +173,14 @@ *unit = NULL; - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, u) { if (u->fcp_lun == lun) { *unit = u; } } - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); if (NULL == *unit) { ret = -ENOUNI; } @@ -214,14 +214,14 @@ *port = NULL; - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, p) { if (p->wwpn == wwpn) { *port = p; } } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); if (NULL == *port) { ret = -ENOPOR; @@ -268,7 +268,7 @@ *adapter = NULL; - ZFCP_READ_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + read_lock_irqsave(&zfcp_data.adapter_list_lock, flags); ZFCP_FOR_EACH_ADAPTER(a) { if (a->devno == devno) { @@ -282,7 +282,7 @@ break; } } - ZFCP_READ_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + read_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); if (NULL == *adapter) { ret = -ENOADA; } else { @@ -310,7 +310,7 @@ unsigned long flags; int ret = 0; - ZFCP_READ_LOCK_IRQSAVE(&port->unit_list_lock, flags); + read_lock_irqsave(&port->unit_list_lock, flags); ZFCP_FOR_EACH_UNIT(port, unit) { @@ -320,7 +320,7 @@ } } - ZFCP_READ_UNLOCK_IRQRESTORE(&port->unit_list_lock, flags); + read_unlock_irqrestore(&port->unit_list_lock, flags); return ret; } @@ -338,7 +338,7 @@ unsigned long flags; int ret = 0; - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { @@ -358,7 +358,7 @@ } } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); return ret; } @@ -380,7 +380,7 @@ unsigned long flags; int ret = 0; - ZFCP_READ_LOCK_IRQSAVE(&zfcp_data.adapter_list_lock, flags); + read_lock_irqsave(&zfcp_data.adapter_list_lock, flags); ZFCP_FOR_EACH_ADAPTER(adapter) { @@ -399,7 +399,7 @@ } } - ZFCP_READ_UNLOCK_IRQRESTORE(&zfcp_data.adapter_list_lock, flags); + read_unlock_irqrestore(&zfcp_data.adapter_list_lock, flags); return ret; } @@ -535,7 +535,7 @@ attr->discovered_ports = adapter->ports; /* ignore nameserver port */ - ZFCP_READ_LOCK_IRQSAVE(&adapter->port_list_lock, flags); + read_lock_irqsave(&adapter->port_list_lock, flags); ZFCP_FOR_EACH_PORT(adapter, port) { if(port->wwpn == 0){ @@ -544,7 +544,7 @@ break; } } - ZFCP_READ_UNLOCK_IRQRESTORE(&adapter->port_list_lock, flags); + read_unlock_irqrestore(&adapter->port_list_lock, flags); if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){ ret = zfcp_fsf_exchange_port_data(adapter, &data); --- linux-2.4.26/include/asm-s390/fsf.h.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/include/asm-s390/fsf.h 1969-12-31 19:00:00.000000000 -0500 @@ -1,365 +0,0 @@ -/* - * header file for FCP adapter driver for IBM eServer zSeries - * - * Authors: - * Martin Peschke - * Raimund Schroeder - * Aron Zeh - * Wolfgang Taphorn - * - * Copyright (C) 2002 IBM Entwicklung GmbH, IBM Corporation - */ - -#ifndef FSF_H -#define FSF_H - -#define FSF_QTCB_VERSION1 0x00000001 -#define FSF_QTCB_CURRENT_VERSION FSF_QTCB_VERSION1 - -/* FSF commands */ -#define FSF_QTCB_FCP_CMND 0x00000001 -#define FSF_QTCB_ABORT_FCP_CMND 0x00000002 -#define FSF_QTCB_OPEN_PORT_WITH_DID 0x00000005 -#define FSF_QTCB_OPEN_LUN 0x00000006 -#define FSF_QTCB_CLOSE_LUN 0x00000007 -#define FSF_QTCB_CLOSE_PORT 0x00000008 -#define FSF_QTCB_CLOSE_PHYSICAL_PORT 0x00000009 -#define FSF_QTCB_SEND_ELS 0x0000000B -#define FSF_QTCB_SEND_GENERIC 0x0000000C -#define FSF_QTCB_EXCHANGE_CONFIG_DATA 0x0000000D -#define FSF_QTCB_DOWNLOAD_CONTROL_FILE 0x00000012 -#define FSF_QTCB_UPLOAD_CONTROL_FILE 0x00000013 - -/* FSF QTCB types */ -#define FSF_IO_COMMAND 0x00000001 -#define FSF_SUPPORT_COMMAND 0x00000002 -#define FSF_CONFIG_COMMAND 0x00000003 - -/* FSF control file upload/download operations' subtype and options */ -#define FSF_ACT_OPERATION_SUBTYPE 0x00020001 -#define FSF_ACT_OPTION_NORMAL_MODE 0x00000000 -#define FSF_ACT_OPTION_FORCE 0x00000001 -#define FSF_ACT_OPTION_FULL_ACCESS 0x00000002 -#define FSF_ACT_OPTION_RESTRICTED_ACCESS 0x00000004 - -/* FSF protocol stati */ -#define FSF_PROT_GOOD 0x00000001 -#define FSF_PROT_QTCB_VERSION_ERROR 0x00000010 -#define FSF_PROT_SEQ_NUMB_ERROR 0x00000020 -#define FSF_PROT_UNSUPP_QTCB_TYPE 0x00000040 -#define FSF_PROT_HOST_CONNECTION_INITIALIZING 0x00000080 -#define FSF_PROT_FSF_STATUS_PRESENTED 0x00000100 -#define FSF_PROT_DUPLICATE_REQUEST_ID 0x00000200 -#define FSF_PROT_LINK_DOWN 0x00000400 -#define FSF_PROT_REEST_QUEUE 0x00000800 -#define FSF_PROT_ERROR_STATE 0x01000000 - -/* FSF stati */ -#define FSF_GOOD 0x00000000 -#define FSF_PORT_ALREADY_OPEN 0x00000001 -#define FSF_LUN_ALREADY_OPEN 0x00000002 -#define FSF_PORT_HANDLE_NOT_VALID 0x00000003 -#define FSF_LUN_HANDLE_NOT_VALID 0x00000004 -#define FSF_HANDLE_MISMATCH 0x00000005 -#define FSF_SERVICE_CLASS_NOT_SUPPORTED 0x00000006 -#define FSF_FCPLUN_NOT_VALID 0x00000009 -#define FSF_ACCESS_DENIED 0x00000010 -#define FSF_ACCESS_TYPE_NOT_VALID 0x00000011 -#define FSF_LUN_SHARING_VIOLATION 0x00000012 -#define FSF_COMMAND_ABORTED_ULP 0x00000020 -#define FSF_COMMAND_ABORTED_ADAPTER 0x00000021 -#define FSF_FCP_COMMAND_DOES_NOT_EXIST 0x00000022 -#define FSF_DIRECTION_INDICATOR_NOT_VALID 0x00000030 -#define FSF_INBOUND_DATA_LENGTH_NOT_VALID 0x00000031 /* FIXME: obsolete? */ -#define FSF_OUTBOUND_DATA_LENGTH_NOT_VALID 0x00000032 /* FIXME: obsolete? */ -#define FSF_CMND_LENGTH_NOT_VALID 0x00000033 -#define FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED 0x00000040 -#define FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED 0x00000041 -#define FSF_REQUEST_BUF_NOT_VALID 0x00000042 -#define FSF_RESPONSE_BUF_NOT_VALID 0x00000043 -#define FSF_ELS_COMMAND_REJECTED 0x00000050 -#define FSF_GENERIC_COMMAND_REJECTED 0x00000051 -#define FSF_OPERATION_PARTIALLY_SUCCESSFUL 0x00000052 -#define FSF_AUTHORIZATION_FAILURE 0x00000053 -#define FSF_ACT_ERROR_DETECTED 0x00000054 -#define FSF_CONTROL_FILE_UPDATE_ERROR 0x00000055 -#define FSF_CONTROL_FILE_TOO_LARGE 0x00000056 -#define FSF_ACCESS_CONFLICT_DETECTED 0x00000057 -#define FSF_CONFLICTS_OVERRULED 0x00000058 -#define FSF_PORT_BOXED 0x00000059 -#define FSF_LUN_BOXED 0x0000005A -#define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD -#define FSF_FCP_RSP_AVAILABLE 0x000000AF -#define FSF_UNKNOWN_COMMAND 0x000000E2 -#define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3 -#define FSF_INVALID_COMMAND_OPTION 0x000000E5 -//#define FSF_ERROR 0x000000FF - -/* FSF status qualifier, recommendations */ -#define FSF_SQ_NO_RECOM 0x00 -#define FSF_SQ_FCP_RSP_AVAILABLE 0x01 -#define FSF_SQ_RETRY_IF_POSSIBLE 0x02 -#define FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED 0x03 -#define FSF_SQ_INVOKE_LINK_TEST_PROCEDURE 0x04 -#define FSF_SQ_ULP_PROGRAMMING_ERROR 0x05 -#define FSF_SQ_COMMAND_ABORTED 0x06 -#define FSF_SQ_NO_RETRY_POSSIBLE 0x07 - -/* FSF status qualifier for ACT download/upload commands */ -#define FSF_SQ_ACT_COULD_NOT_HARDEN_ON_SE 0x00000001 -#define FSF_SQ_ACT_COULD_NOT_HARDEN_ON_SE2 0x00000002 -/* ACT subtable codes */ -#define FSF_SQ_ACT_SUBTABLE_OS 0x0001 -#define FSF_SQ_ACT_SUBTABLE_PORT_WWPN 0x0002 -#define FSF_SQ_ACT_SUBTABLE_PORT_DID 0x0003 -#define FSF_SQ_ACT_SUBTABLE_LUN 0x0004 - -/* FSF status qualifier (most significant 4 bytes), local link down */ -#define FSF_PSQ_LINK_NOLIGHT 0x00000004 -#define FSF_PSQ_LINK_WRAPPLUG 0x00000008 -#define FSF_PSQ_LINK_NOFCP 0x00000010 - -/* payload size in status read buffer */ -#define FSF_STATUS_READ_PAYLOAD_SIZE 4032 - -/* number of status read buffers that should be sent by ULP */ -#define FSF_STATUS_READS_RECOM 16 - -/* status types in status read buffer */ -#define FSF_STATUS_READ_PORT_CLOSED 0x00000001 -#define FSF_STATUS_READ_INCOMING_ELS 0x00000002 -#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004 -#define FSF_STATUS_READ_LINK_DOWN 0x00000005 /* FIXME: really? */ -#define FSF_STATUS_READ_LINK_UP 0x00000006 -#define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009 -#define FSF_STATUS_READ_ACT_UPDATED 0x0000000A -#define FSF_STATUS_READ_ACT_HARDENED 0x0000000B - -/* status subtypes in status read buffer */ -#define FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT 0x00000001 -#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002 -#define FSF_STATUS_READ_SUB_LOST_ACT_UPDATED 0x00000020 -#define FSF_STATUS_READ_SUB_LOST_ACT_HARDENED 0x00000040 -#define FSF_STATUS_READ_SUB_ACT_HARDENED_ON_SE 0x00000002 -#define FSF_STATUS_READ_SUB_ACT_HARDENED_ON_SE2 0x0000000F - -#define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001 - -/* topologie that is detected by the adapter */ -#define FSF_TOPO_ERROR 0x00000000 -#define FSF_TOPO_P2P 0x00000001 -#define FSF_TOPO_FABRIC 0x00000002 -#define FSF_TOPO_AL 0x00000003 -#define FSF_TOPO_FABRIC_VIRT 0x00000004 - -/* data direction for FCP commands */ -#define FSF_DATADIR_WRITE 0x00000001 -#define FSF_DATADIR_READ 0x00000002 -#define FSF_DATADIR_READ_WRITE 0x00000003 -#define FSF_DATADIR_CMND 0x00000004 - -/* fc service class */ -#define FSF_CLASS_1 0x00000001 -#define FSF_CLASS_2 0x00000002 -#define FSF_CLASS_3 0x00000003 - -/* SBAL chaining */ -#define FSF_MAX_SBALS_PER_REQ 36 - -/* logging space behind QTCB */ -#define FSF_QTCB_LOG_SIZE 1024 - -struct fsf_queue_designator; -struct fsf_status_read_buffer; -struct fsf_port_closed_payload; -struct fsf_bit_error_payload; -union fsf_prot_status_qual; -struct fsf_qual_version_error; -struct fsf_qual_sequence_error; -struct fsf_qtcb_prefix; -struct fsf_qtcb_header; -struct fsf_qtcb_bottom_config; -struct fsf_qtcb_bottom_support; -struct fsf_qtcb_bottom_io; -union fsf_qtcb_bottom; - -typedef struct fsf_queue_designator { - u8 cssid; - u8 chpid; - u8 hla; - u8 ua; - u32 res1; -} __attribute__ ((packed)) fsf_queue_designator_t; - -typedef struct fsf_port_closed_payload { - fsf_queue_designator_t queue_designator; - u32 port_handle; -} __attribute__ ((packed)) fsf_port_closed_payload_t; - -typedef struct fsf_bit_error_payload { - u32 res1; - u32 link_failure_error_count; - u32 loss_of_sync_error_count; - u32 loss_of_signal_error_count; - u32 primitive_sequence_error_count; - u32 invalid_transmission_word_error_count; - u32 crc_error_count; - u32 primitive_sequence_event_timeout_count; - u32 elastic_buffer_overrun_error_count; - u32 fcal_arbitration_timeout_count; - u32 advertised_receive_b2b_credit; - u32 current_receive_b2b_credit; - u32 advertised_transmit_b2b_credit; - u32 current_transmit_b2b_credit; -} __attribute__ ((packed)) fsf_bit_error_payload_t; - -typedef struct fsf_status_read_buffer { - u32 status_type; - u32 status_subtype; - u32 length; - u32 res1; - fsf_queue_designator_t queue_designator; - u32 d_id; - u32 class; - u64 fcp_lun; - u8 res3[24]; - u8 payload[FSF_STATUS_READ_PAYLOAD_SIZE]; -} __attribute__ ((packed)) fsf_status_read_buffer_t; - -typedef struct fsf_qual_version_error { - u32 fsf_version; - u32 res1[3]; -} __attribute__ ((packed)) fsf_qual_version_error_t; - -typedef struct fsf_qual_sequence_error { - u32 exp_req_seq_no; - u32 res1[3]; -} __attribute__ ((packed)) fsf_qual_sequence_error_t; - -typedef struct fsf_qual_locallink_error { - u32 code; - u32 res1[3]; -} __attribute__ ((packed)) fsf_qual_locallink_error_t; - -typedef union fsf_prot_status_qual { - fsf_qual_version_error_t version_error; - fsf_qual_sequence_error_t sequence_error; - fsf_qual_locallink_error_t locallink_error; -} __attribute__ ((packed)) fsf_prot_status_qual_t; - -typedef struct fsf_qtcb_prefix { - u64 req_id; - u32 qtcb_version; - u32 ulp_info; - u32 qtcb_type; - u32 req_seq_no; - u32 prot_status; - fsf_prot_status_qual_t prot_status_qual; - u8 res1[20]; -} __attribute__ ((packed)) fsf_qtcb_prefix_t; - -typedef union fsf_status_qual { -#define FSF_STATUS_QUAL_SIZE 16 - u8 byte[FSF_STATUS_QUAL_SIZE]; - u16 halfword[FSF_STATUS_QUAL_SIZE / sizeof(u16)]; - u32 word[FSF_STATUS_QUAL_SIZE / sizeof(u32)]; -} __attribute__ ((packed)) fsf_status_qual_t; - -typedef struct fsf_qtcb_header { - u64 req_handle; - u32 fsf_command; - u32 res1; - u32 port_handle; - u32 lun_handle; - u32 res2; - u32 fsf_status; - fsf_status_qual_t fsf_status_qual; - u8 res3[28]; - u16 log_start; - u16 log_length; - u8 res4[16]; -} __attribute__ ((packed)) fsf_qtcb_header_t; - -typedef u64 fsf_wwn_t; - -typedef struct fsf_nport_serv_param { - u8 common_serv_param[16]; - fsf_wwn_t wwpn; - fsf_wwn_t wwnn; - u8 class1_serv_param[16]; - u8 class2_serv_param[16]; - u8 class3_serv_param[16]; - u8 class4_serv_param[16]; - u8 vendor_version_level[16]; - u8 res1[16]; -} __attribute__ ((packed)) fsf_nport_serv_param_t; - -typedef struct fsf_plogi { - u32 code; - fsf_nport_serv_param_t serv_param; -} __attribute__ ((packed)) fsf_plogi_t; - -#define FSF_FCP_CMND_SIZE 288 -#define FSF_FCP_RSP_SIZE 128 - -typedef struct fsf_qtcb_bottom_io { - u32 data_direction; - u32 service_class; - u8 res1[8]; - u32 fcp_cmnd_length; - u8 res2[12]; - u8 fcp_cmnd[FSF_FCP_CMND_SIZE]; - u8 fcp_rsp[FSF_FCP_RSP_SIZE]; - u8 res3[64]; -} __attribute__ ((packed)) fsf_qtcb_bottom_io_t; - -typedef struct fsf_qtcb_bottom_support { - u32 operation_subtype; - u8 res1[12]; - u32 d_id; - u32 option; - u64 fcp_lun; - u64 res3; - u64 req_handle; - u32 service_class; - u8 res4[3]; - u8 timeout; - u8 res5[184]; - u32 els1_length; - u32 els2_length; - u64 res6; - u8 els[256]; -} __attribute__ ((packed)) fsf_qtcb_bottom_support_t; - -typedef struct fsf_qtcb_bottom_config { - u32 lic_version; - u32 feature_selection; - u32 high_qtcb_version; - u32 low_qtcb_version; - u32 max_qtcb_size; - u8 res1[4]; - u32 features_supported; - u8 res2[4]; - u32 fc_topology; - u32 fc_link_speed; - u32 adapter_type; - u32 peer_d_id; - u8 res3[12]; - u32 s_id; - fsf_nport_serv_param_t nport_serv_param; - u8 res4[320]; -} __attribute__ ((packed)) fsf_qtcb_bottom_config_t; - -typedef union fsf_qtcb_bottom { - fsf_qtcb_bottom_io_t io; - fsf_qtcb_bottom_support_t support; - fsf_qtcb_bottom_config_t config; -} fsf_qtcb_bottom_t; - -typedef struct fsf_qtcb { - fsf_qtcb_prefix_t prefix; - fsf_qtcb_header_t header; - fsf_qtcb_bottom_t bottom; -} __attribute__ ((packed)) fsf_qtcb_t; - -#endif /* FSF_H */ --- linux-2.4.26/include/asm-s390x/fsf.h.orig 2004-09-18 19:02:13.000000000 -0400 +++ linux-2.4.26/include/asm-s390x/fsf.h 1969-12-31 19:00:00.000000000 -0500 @@ -1,365 +0,0 @@ -/* - * header file for FCP adapter driver for IBM eServer zSeries - * - * Authors: - * Martin Peschke - * Raimund Schroeder - * Aron Zeh - * Wolfgang Taphorn - * - * Copyright (C) 2002 IBM Entwicklung GmbH, IBM Corporation - */ - -#ifndef FSF_H -#define FSF_H - -#define FSF_QTCB_VERSION1 0x00000001 -#define FSF_QTCB_CURRENT_VERSION FSF_QTCB_VERSION1 - -/* FSF commands */ -#define FSF_QTCB_FCP_CMND 0x00000001 -#define FSF_QTCB_ABORT_FCP_CMND 0x00000002 -#define FSF_QTCB_OPEN_PORT_WITH_DID 0x00000005 -#define FSF_QTCB_OPEN_LUN 0x00000006 -#define FSF_QTCB_CLOSE_LUN 0x00000007 -#define FSF_QTCB_CLOSE_PORT 0x00000008 -#define FSF_QTCB_CLOSE_PHYSICAL_PORT 0x00000009 -#define FSF_QTCB_SEND_ELS 0x0000000B -#define FSF_QTCB_SEND_GENERIC 0x0000000C -#define FSF_QTCB_EXCHANGE_CONFIG_DATA 0x0000000D -#define FSF_QTCB_DOWNLOAD_CONTROL_FILE 0x00000012 -#define FSF_QTCB_UPLOAD_CONTROL_FILE 0x00000013 - -/* FSF QTCB types */ -#define FSF_IO_COMMAND 0x00000001 -#define FSF_SUPPORT_COMMAND 0x00000002 -#define FSF_CONFIG_COMMAND 0x00000003 - -/* FSF control file upload/download operations' subtype and options */ -#define FSF_ACT_OPERATION_SUBTYPE 0x00020001 -#define FSF_ACT_OPTION_NORMAL_MODE 0x00000000 -#define FSF_ACT_OPTION_FORCE 0x00000001 -#define FSF_ACT_OPTION_FULL_ACCESS 0x00000002 -#define FSF_ACT_OPTION_RESTRICTED_ACCESS 0x00000004 - -/* FSF protocol stati */ -#define FSF_PROT_GOOD 0x00000001 -#define FSF_PROT_QTCB_VERSION_ERROR 0x00000010 -#define FSF_PROT_SEQ_NUMB_ERROR 0x00000020 -#define FSF_PROT_UNSUPP_QTCB_TYPE 0x00000040 -#define FSF_PROT_HOST_CONNECTION_INITIALIZING 0x00000080 -#define FSF_PROT_FSF_STATUS_PRESENTED 0x00000100 -#define FSF_PROT_DUPLICATE_REQUEST_ID 0x00000200 -#define FSF_PROT_LINK_DOWN 0x00000400 -#define FSF_PROT_REEST_QUEUE 0x00000800 -#define FSF_PROT_ERROR_STATE 0x01000000 - -/* FSF stati */ -#define FSF_GOOD 0x00000000 -#define FSF_PORT_ALREADY_OPEN 0x00000001 -#define FSF_LUN_ALREADY_OPEN 0x00000002 -#define FSF_PORT_HANDLE_NOT_VALID 0x00000003 -#define FSF_LUN_HANDLE_NOT_VALID 0x00000004 -#define FSF_HANDLE_MISMATCH 0x00000005 -#define FSF_SERVICE_CLASS_NOT_SUPPORTED 0x00000006 -#define FSF_FCPLUN_NOT_VALID 0x00000009 -#define FSF_ACCESS_DENIED 0x00000010 -#define FSF_ACCESS_TYPE_NOT_VALID 0x00000011 -#define FSF_LUN_SHARING_VIOLATION 0x00000012 -#define FSF_COMMAND_ABORTED_ULP 0x00000020 -#define FSF_COMMAND_ABORTED_ADAPTER 0x00000021 -#define FSF_FCP_COMMAND_DOES_NOT_EXIST 0x00000022 -#define FSF_DIRECTION_INDICATOR_NOT_VALID 0x00000030 -#define FSF_INBOUND_DATA_LENGTH_NOT_VALID 0x00000031 /* FIXME: obsolete? */ -#define FSF_OUTBOUND_DATA_LENGTH_NOT_VALID 0x00000032 /* FIXME: obsolete? */ -#define FSF_CMND_LENGTH_NOT_VALID 0x00000033 -#define FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED 0x00000040 -#define FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED 0x00000041 -#define FSF_REQUEST_BUF_NOT_VALID 0x00000042 -#define FSF_RESPONSE_BUF_NOT_VALID 0x00000043 -#define FSF_ELS_COMMAND_REJECTED 0x00000050 -#define FSF_GENERIC_COMMAND_REJECTED 0x00000051 -#define FSF_OPERATION_PARTIALLY_SUCCESSFUL 0x00000052 -#define FSF_AUTHORIZATION_FAILURE 0x00000053 -#define FSF_ACT_ERROR_DETECTED 0x00000054 -#define FSF_CONTROL_FILE_UPDATE_ERROR 0x00000055 -#define FSF_CONTROL_FILE_TOO_LARGE 0x00000056 -#define FSF_ACCESS_CONFLICT_DETECTED 0x00000057 -#define FSF_CONFLICTS_OVERRULED 0x00000058 -#define FSF_PORT_BOXED 0x00000059 -#define FSF_LUN_BOXED 0x0000005A -#define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD -#define FSF_FCP_RSP_AVAILABLE 0x000000AF -#define FSF_UNKNOWN_COMMAND 0x000000E2 -#define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3 -#define FSF_INVALID_COMMAND_OPTION 0x000000E5 -//#define FSF_ERROR 0x000000FF - -/* FSF status qualifier, recommendations */ -#define FSF_SQ_NO_RECOM 0x00 -#define FSF_SQ_FCP_RSP_AVAILABLE 0x01 -#define FSF_SQ_RETRY_IF_POSSIBLE 0x02 -#define FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED 0x03 -#define FSF_SQ_INVOKE_LINK_TEST_PROCEDURE 0x04 -#define FSF_SQ_ULP_PROGRAMMING_ERROR 0x05 -#define FSF_SQ_COMMAND_ABORTED 0x06 -#define FSF_SQ_NO_RETRY_POSSIBLE 0x07 - -/* FSF status qualifier for ACT download/upload commands */ -#define FSF_SQ_ACT_COULD_NOT_HARDEN_ON_SE 0x00000001 -#define FSF_SQ_ACT_COULD_NOT_HARDEN_ON_SE2 0x00000002 -/* ACT subtable codes */ -#define FSF_SQ_ACT_SUBTABLE_OS 0x0001 -#define FSF_SQ_ACT_SUBTABLE_PORT_WWPN 0x0002 -#define FSF_SQ_ACT_SUBTABLE_PORT_DID 0x0003 -#define FSF_SQ_ACT_SUBTABLE_LUN 0x0004 - -/* FSF status qualifier (most significant 4 bytes), local link down */ -#define FSF_PSQ_LINK_NOLIGHT 0x00000004 -#define FSF_PSQ_LINK_WRAPPLUG 0x00000008 -#define FSF_PSQ_LINK_NOFCP 0x00000010 - -/* payload size in status read buffer */ -#define FSF_STATUS_READ_PAYLOAD_SIZE 4032 - -/* number of status read buffers that should be sent by ULP */ -#define FSF_STATUS_READS_RECOM 16 - -/* status types in status read buffer */ -#define FSF_STATUS_READ_PORT_CLOSED 0x00000001 -#define FSF_STATUS_READ_INCOMING_ELS 0x00000002 -#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004 -#define FSF_STATUS_READ_LINK_DOWN 0x00000005 /* FIXME: really? */ -#define FSF_STATUS_READ_LINK_UP 0x00000006 -#define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009 -#define FSF_STATUS_READ_ACT_UPDATED 0x0000000A -#define FSF_STATUS_READ_ACT_HARDENED 0x0000000B - -/* status subtypes in status read buffer */ -#define FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT 0x00000001 -#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002 -#define FSF_STATUS_READ_SUB_LOST_ACT_UPDATED 0x00000020 -#define FSF_STATUS_READ_SUB_LOST_ACT_HARDENED 0x00000040 -#define FSF_STATUS_READ_SUB_ACT_HARDENED_ON_SE 0x00000002 -#define FSF_STATUS_READ_SUB_ACT_HARDENED_ON_SE2 0x0000000F - -#define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001 - -/* topologie that is detected by the adapter */ -#define FSF_TOPO_ERROR 0x00000000 -#define FSF_TOPO_P2P 0x00000001 -#define FSF_TOPO_FABRIC 0x00000002 -#define FSF_TOPO_AL 0x00000003 -#define FSF_TOPO_FABRIC_VIRT 0x00000004 - -/* data direction for FCP commands */ -#define FSF_DATADIR_WRITE 0x00000001 -#define FSF_DATADIR_READ 0x00000002 -#define FSF_DATADIR_READ_WRITE 0x00000003 -#define FSF_DATADIR_CMND 0x00000004 - -/* fc service class */ -#define FSF_CLASS_1 0x00000001 -#define FSF_CLASS_2 0x00000002 -#define FSF_CLASS_3 0x00000003 - -/* SBAL chaining */ -#define FSF_MAX_SBALS_PER_REQ 36 - -/* logging space behind QTCB */ -#define FSF_QTCB_LOG_SIZE 1024 - -struct fsf_queue_designator; -struct fsf_status_read_buffer; -struct fsf_port_closed_payload; -struct fsf_bit_error_payload; -union fsf_prot_status_qual; -struct fsf_qual_version_error; -struct fsf_qual_sequence_error; -struct fsf_qtcb_prefix; -struct fsf_qtcb_header; -struct fsf_qtcb_bottom_config; -struct fsf_qtcb_bottom_support; -struct fsf_qtcb_bottom_io; -union fsf_qtcb_bottom; - -typedef struct fsf_queue_designator { - u8 cssid; - u8 chpid; - u8 hla; - u8 ua; - u32 res1; -} __attribute__ ((packed)) fsf_queue_designator_t; - -typedef struct fsf_port_closed_payload { - fsf_queue_designator_t queue_designator; - u32 port_handle; -} __attribute__ ((packed)) fsf_port_closed_payload_t; - -typedef struct fsf_bit_error_payload { - u32 res1; - u32 link_failure_error_count; - u32 loss_of_sync_error_count; - u32 loss_of_signal_error_count; - u32 primitive_sequence_error_count; - u32 invalid_transmission_word_error_count; - u32 crc_error_count; - u32 primitive_sequence_event_timeout_count; - u32 elastic_buffer_overrun_error_count; - u32 fcal_arbitration_timeout_count; - u32 advertised_receive_b2b_credit; - u32 current_receive_b2b_credit; - u32 advertised_transmit_b2b_credit; - u32 current_transmit_b2b_credit; -} __attribute__ ((packed)) fsf_bit_error_payload_t; - -typedef struct fsf_status_read_buffer { - u32 status_type; - u32 status_subtype; - u32 length; - u32 res1; - fsf_queue_designator_t queue_designator; - u32 d_id; - u32 class; - u64 fcp_lun; - u8 res3[24]; - u8 payload[FSF_STATUS_READ_PAYLOAD_SIZE]; -} __attribute__ ((packed)) fsf_status_read_buffer_t; - -typedef struct fsf_qual_version_error { - u32 fsf_version; - u32 res1[3]; -} __attribute__ ((packed)) fsf_qual_version_error_t; - -typedef struct fsf_qual_sequence_error { - u32 exp_req_seq_no; - u32 res1[3]; -} __attribute__ ((packed)) fsf_qual_sequence_error_t; - -typedef struct fsf_qual_locallink_error { - u32 code; - u32 res1[3]; -} __attribute__ ((packed)) fsf_qual_locallink_error_t; - -typedef union fsf_prot_status_qual { - fsf_qual_version_error_t version_error; - fsf_qual_sequence_error_t sequence_error; - fsf_qual_locallink_error_t locallink_error; -} __attribute__ ((packed)) fsf_prot_status_qual_t; - -typedef struct fsf_qtcb_prefix { - u64 req_id; - u32 qtcb_version; - u32 ulp_info; - u32 qtcb_type; - u32 req_seq_no; - u32 prot_status; - fsf_prot_status_qual_t prot_status_qual; - u8 res1[20]; -} __attribute__ ((packed)) fsf_qtcb_prefix_t; - -typedef union fsf_status_qual { -#define FSF_STATUS_QUAL_SIZE 16 - u8 byte[FSF_STATUS_QUAL_SIZE]; - u16 halfword[FSF_STATUS_QUAL_SIZE / sizeof(u16)]; - u32 word[FSF_STATUS_QUAL_SIZE / sizeof(u32)]; -} __attribute__ ((packed)) fsf_status_qual_t; - -typedef struct fsf_qtcb_header { - u64 req_handle; - u32 fsf_command; - u32 res1; - u32 port_handle; - u32 lun_handle; - u32 res2; - u32 fsf_status; - fsf_status_qual_t fsf_status_qual; - u8 res3[28]; - u16 log_start; - u16 log_length; - u8 res4[16]; -} __attribute__ ((packed)) fsf_qtcb_header_t; - -typedef u64 fsf_wwn_t; - -typedef struct fsf_nport_serv_param { - u8 common_serv_param[16]; - fsf_wwn_t wwpn; - fsf_wwn_t wwnn; - u8 class1_serv_param[16]; - u8 class2_serv_param[16]; - u8 class3_serv_param[16]; - u8 class4_serv_param[16]; - u8 vendor_version_level[16]; - u8 res1[16]; -} __attribute__ ((packed)) fsf_nport_serv_param_t; - -typedef struct fsf_plogi { - u32 code; - fsf_nport_serv_param_t serv_param; -} __attribute__ ((packed)) fsf_plogi_t; - -#define FSF_FCP_CMND_SIZE 288 -#define FSF_FCP_RSP_SIZE 128 - -typedef struct fsf_qtcb_bottom_io { - u32 data_direction; - u32 service_class; - u8 res1[8]; - u32 fcp_cmnd_length; - u8 res2[12]; - u8 fcp_cmnd[FSF_FCP_CMND_SIZE]; - u8 fcp_rsp[FSF_FCP_RSP_SIZE]; - u8 res3[64]; -} __attribute__ ((packed)) fsf_qtcb_bottom_io_t; - -typedef struct fsf_qtcb_bottom_support { - u32 operation_subtype; - u8 res1[12]; - u32 d_id; - u32 option; - u64 fcp_lun; - u64 res3; - u64 req_handle; - u32 service_class; - u8 res4[3]; - u8 timeout; - u8 res5[184]; - u32 els1_length; - u32 els2_length; - u64 res6; - u8 els[256]; -} __attribute__ ((packed)) fsf_qtcb_bottom_support_t; - -typedef struct fsf_qtcb_bottom_config { - u32 lic_version; - u32 feature_selection; - u32 high_qtcb_version; - u32 low_qtcb_version; - u32 max_qtcb_size; - u8 res1[4]; - u32 features_supported; - u8 res2[4]; - u32 fc_topology; - u32 fc_link_speed; - u32 adapter_type; - u32 peer_d_id; - u8 res3[12]; - u32 s_id; - fsf_nport_serv_param_t nport_serv_param; - u8 res4[320]; -} __attribute__ ((packed)) fsf_qtcb_bottom_config_t; - -typedef union fsf_qtcb_bottom { - fsf_qtcb_bottom_io_t io; - fsf_qtcb_bottom_support_t support; - fsf_qtcb_bottom_config_t config; -} fsf_qtcb_bottom_t; - -typedef struct fsf_qtcb { - fsf_qtcb_prefix_t prefix; - fsf_qtcb_header_t header; - fsf_qtcb_bottom_t bottom; -} __attribute__ ((packed)) fsf_qtcb_t; - -#endif /* FSF_H */ --- linux-2.4.26/include/linux/igmp.h.orig 2003-08-25 07:44:44.000000000 -0400 +++ linux-2.4.26/include/linux/igmp.h 2004-09-18 19:02:14.000000000 -0400 @@ -193,6 +193,9 @@ #define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value) #define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value) +extern int register_multicast_notifier(struct notifier_block *nb); +extern int unregister_multicast_notifier(struct notifier_block *nb); + extern int ip_check_mc(struct in_device *dev, u32 mc_addr, u32 src_addr); extern int igmp_rcv(struct sk_buff *); extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr); --- linux-2.4.26/include/net/addrconf.h.orig 2003-08-25 07:44:44.000000000 -0400 +++ linux-2.4.26/include/net/addrconf.h 2004-09-18 19:02:14.000000000 -0400 @@ -71,6 +71,9 @@ /* * multicast prototypes (mcast.c) */ +extern int register_multicast6_notifier(struct notifier_block *nb); +extern int unregister_multicast6_notifier(struct notifier_block *nb); + extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr); extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, --- linux-2.4.26/net/ipv4/devinet.c.orig 2004-09-18 19:02:14.000000000 -0400 +++ linux-2.4.26/net/ipv4/devinet.c 2004-09-18 19:02:14.000000000 -0400 @@ -65,7 +65,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr *); -struct notifier_block *inetaddr_chain; +static struct notifier_block *inetaddr_chain; static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy); #ifdef CONFIG_SYSCTL static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p); --- linux-2.4.26/net/ipv4/igmp.c.orig 2004-09-18 19:02:14.000000000 -0400 +++ linux-2.4.26/net/ipv4/igmp.c 2004-09-18 19:02:14.000000000 -0400 @@ -152,6 +152,18 @@ #ifdef CONFIG_IP_MULTICAST +static struct notifier_block *multicast_chain; + +int register_multicast_notifier(struct notifier_block *nb) +{ + return notifier_chain_register(&multicast_chain, nb); +} + +int unregister_multicast_notifier(struct notifier_block *nb) +{ + return notifier_chain_unregister(&multicast_chain,nb); +} + /* * Timer management */ @@ -1164,7 +1176,7 @@ igmp_group_added(im); if (!in_dev->dead) ip_rt_multicast_event(in_dev); - notifier_call_chain(&inetaddr_chain, NETDEV_CHANGE, in_dev->dev); + notifier_call_chain(&multicast_chain, NETDEV_REGISTER, im); out: return; } @@ -1190,10 +1202,10 @@ if (!in_dev->dead) ip_rt_multicast_event(in_dev); + notifier_call_chain(&multicast_chain, + NETDEV_UNREGISTER, + i); ip_ma_put(i); - notifier_call_chain(&inetaddr_chain, - NETDEV_CHANGE, - in_dev->dev); return; } break; --- linux-2.4.26/net/ipv6/addrconf.c.orig 2004-09-18 19:02:14.000000000 -0400 +++ linux-2.4.26/net/ipv6/addrconf.c 2004-09-18 19:02:14.000000000 -0400 @@ -111,7 +111,7 @@ static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); -struct notifier_block *inet6addr_chain; +static struct notifier_block *inet6addr_chain; struct ipv6_devconf ipv6_devconf = { --- linux-2.4.26/net/ipv6/mcast.c.orig 2004-09-18 19:02:14.000000000 -0400 +++ linux-2.4.26/net/ipv6/mcast.c 2004-09-18 19:02:14.000000000 -0400 @@ -127,6 +127,18 @@ static struct socket *igmp6_socket; +static struct notifier_block *multicast_chain; + +int register_multicast6_notifier(struct notifier_block *nb) +{ + return notifier_chain_register(&multicast_chain, nb); +} + +int unregister_multicast6_notifier(struct notifier_block *nb) +{ + return notifier_chain_unregister(&multicast_chain,nb); +} + static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); static void igmp6_timer_handler(unsigned long data); @@ -857,8 +869,8 @@ mld_del_delrec(idev, &mc->mca_addr); igmp6_group_added(mc); + notifier_call_chain(&multicast_chain, NETDEV_REGISTER, mc); ma_put(mc); - notifier_call_chain(&inet6addr_chain, NETDEV_CHANGE, idev->dev); return 0; } @@ -878,9 +890,9 @@ igmp6_group_dropped(ma); + notifier_call_chain(&multicast_chain, + NETDEV_UNREGISTER, ma); ma_put(ma); - notifier_call_chain(&inet6addr_chain, - NETDEV_CHANGE, idev->dev); return 0; } write_unlock_bh(&idev->lock); --- linux-2.4.26/net/netsyms.c.orig 2004-04-14 09:05:41.000000000 -0400 +++ linux-2.4.26/net/netsyms.c 2004-09-18 19:02:14.000000000 -0400 @@ -290,7 +290,10 @@ EXPORT_SYMBOL(devinet_ioctl); EXPORT_SYMBOL(register_inetaddr_notifier); EXPORT_SYMBOL(unregister_inetaddr_notifier); - +#ifdef CONFIG_IP_MULTICAST +EXPORT_SYMBOL(register_multicast_notifier); +EXPORT_SYMBOL(unregister_multicast_notifier); +#endif /* needed for ip_gre -cw */ EXPORT_SYMBOL(ip_statistics); --- linux-2.4.26/net/ipv6/ipv6_syms.c.orig 2004-04-14 09:05:41.000000000 -0400 +++ linux-2.4.26/net/ipv6/ipv6_syms.c 2004-09-18 19:02:14.000000000 -0400 @@ -14,6 +14,8 @@ EXPORT_SYMBOL(ndisc_mc_map); EXPORT_SYMBOL(register_inet6addr_notifier); EXPORT_SYMBOL(unregister_inet6addr_notifier); +EXPORT_SYMBOL(register_multicast6_notifier); +EXPORT_SYMBOL(unregister_multicast6_notifier); EXPORT_SYMBOL(ip6_route_output); #ifdef CONFIG_NETFILTER EXPORT_SYMBOL(ip6_route_me_harder);