2 * drivers/s390/misc/chandev.c
4 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
7 * Generic channel device initialisation support.
11 #define __KERNEL_SYSCALLS__
12 #include <linux/module.h>
13 #include <linux/config.h>
14 #include <linux/types.h>
15 #include <linux/ctype.h>
16 #include <asm/uaccess.h>
17 #include <linux/slab.h>
19 #include <linux/init.h>
20 #include <linux/unistd.h>
21 #include <asm/chandev.h>
22 #include <linux/proc_fs.h>
23 #include <linux/vmalloc.h>
24 #include <asm/s390dyn.h>
25 #include <asm/queue.h>
26 #include <linux/kmod.h>
28 #define MIN(a,b) ((a<b)?a:b)
31 #define MAX(a,b) ((a>b)?a:b)
36 typedef struct chandev_model_info chandev_model_info;
37 struct chandev_model_info
39 struct chandev_model_info *next;
40 chandev_type chan_type;
41 s32 cu_type; /* control unit type -1 = don't care */
42 s16 cu_model; /* control unit model -1 = don't care */
43 s32 dev_type; /* device type -1 = don't care */
44 s16 dev_model; /* device model -1 = don't care */
46 int auto_msck_recovery;
47 u8 default_checksum_received_ip_pkts;
48 u8 default_use_hw_stats; /* where available e.g. lcs */
52 typedef struct chandev chandev;
56 chandev_model_info *model_info;
57 chandev_subchannel_info sch;
61 typedef struct chandev_noauto_range chandev_noauto_range;
62 struct chandev_noauto_range
64 struct chandev_noauto_range *next;
69 typedef struct chandev_force chandev_force;
72 struct chandev_force *next;
73 chandev_type chan_type;
74 s32 devif_num; /* -1 don't care, -2 we are forcing a range e.g. tr0 implies 0 */
77 u16 data_devno; /* only used by gigabit ethernet */
78 s32 memory_usage_in_k;
79 s16 port_protocol_no; /* where available e.g. lcs,-1 don't care */
80 u8 checksum_received_ip_pkts;
81 u8 use_hw_stats; /* where available e.g. lcs */
82 /* claw specific stuff */
83 chandev_claw_info claw;
86 typedef struct chandev_probelist chandev_probelist;
87 struct chandev_probelist
89 struct chandev_probelist *next;
90 chandev_probefunc probefunc;
91 chandev_shutdownfunc shutdownfunc;
92 chandev_msck_notification_func msck_notfunc;
93 chandev_type chan_type;
99 #define default_msck_bits ((1<<(chandev_status_not_oper-1))|(1<<(chandev_status_no_path-1))|(1<<(chandev_status_revalidate-1))|(1<<(chandev_status_gone-1)))
102 static char *msck_status_strs[]=
111 typedef struct chandev_msck_range chandev_msck_range;
112 struct chandev_msck_range
114 struct chandev_msck_range *next;
117 int auto_msck_recovery;
120 static chandev_msck_range *chandev_msck_range_head=NULL;
122 typedef struct chandev_irqinfo chandev_irqinfo;
123 struct chandev_irqinfo
125 chandev_irqinfo *next;
126 chandev_subchannel_info sch;
127 chandev_msck_status msck_status;
128 void (*handler)(int, void *, struct pt_regs *);
129 unsigned long irqflags;
135 chandev_irqinfo *chandev_irqinfo_head=NULL;
137 typedef struct chandev_parms chandev_parms;
141 chandev_type chan_type;
147 static chandev_type chandev_persistent=0;
149 chandev_parms *chandev_parms_head=NULL;
152 typedef struct chandev_activelist chandev_activelist;
153 struct chandev_activelist
155 struct chandev_activelist *next;
156 chandev_irqinfo *read_irqinfo;
157 chandev_irqinfo *write_irqinfo;
158 chandev_irqinfo *data_irqinfo;
159 chandev_probefunc probefunc;
160 chandev_shutdownfunc shutdownfunc;
161 chandev_msck_notification_func msck_notfunc;
162 chandev_unregfunc unreg_dev;
163 chandev_type chan_type;
165 chandev_category category;
166 s32 memory_usage_in_k;
173 static chandev_model_info *chandev_models_head=NULL;
174 /* The only reason chandev_head is a queue is so that net devices */
175 /* will be by default named in the order of their irqs */
176 static qheader chandev_head={NULL,NULL};
177 static chandev_noauto_range *chandev_noauto_head=NULL;
178 static chandev_force *chandev_force_head=NULL;
179 static chandev_probelist *chandev_probelist_head=NULL;
180 static chandev_activelist *chandev_activelist_head=NULL;
181 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
182 int chandev_use_devno_names=FALSE;
184 static int chandev_cautious_auto_detect=TRUE;
185 static atomic_t chandev_conf_read=ATOMIC_INIT(FALSE);
186 static atomic_t chandev_initialised=ATOMIC_INIT(FALSE);
189 static unsigned long chandev_last_machine_check;
192 static struct tq_struct chandev_msck_task_tq;
193 static atomic_t chandev_msck_thread_lock;
194 static atomic_t chandev_new_msck;
195 static unsigned long chandev_last_startmsck_list_update;
201 chandev_first_tag=chandev_start,
203 chandev_num_notify_tags
204 } chandev_userland_notify_tag;
206 static char *userland_notify_strs[]=
212 typedef struct chandev_userland_notify_list chandev_userland_notify_list;
213 struct chandev_userland_notify_list
215 chandev_userland_notify_list *next;
216 chandev_userland_notify_tag tag;
217 chandev_msck_status prev_status;
218 chandev_msck_status curr_status;
223 static chandev_userland_notify_list *chandev_userland_notify_head=NULL;
228 static void chandev_read_conf_if_necessary(void);
229 static void chandev_read_conf(void);
231 #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,3,0)
232 typedef struct net_device net_device;
234 typedef struct device net_device;
236 static inline void init_waitqueue_head(wait_queue_head_t *q)
242 #if LINUX_VERSION_CODE<KERNEL_VERSION(2,3,45)
243 static __inline__ void netif_stop_queue(net_device *dev)
248 static __inline__ void netif_start_queue(net_device *dev)
256 #define CHANDEV_INVALID_LOCK_OWNER -1
257 static long chandev_lock_owner;
258 static int chandev_lock_cnt;
259 static spinlock_t chandev_spinlock;
260 #define CHANDEV_LOCK_DEBUG 0
261 #if CHANDEV_LOCK_DEBUG && !defined(CONFIG_ARCH_S390X)
262 #define CHANDEV_BACKTRACE_LOOPCNT 10
263 void *chandev_first_lock_addr[CHANDEV_BACKTRACE_LOOPCNT],
264 *chandev_last_lock_addr[CHANDEV_BACKTRACE_LOOPCNT],
265 *chandev_last_unlock_addr[CHANDEV_BACKTRACE_LOOPCNT];
266 #define CHANDEV_BACKTRACE(variable) \
267 memset((variable),0,sizeof(void *)*CHANDEV_BACKTRACE_LOOPCNT); \
268 (variable)[0]=__builtin_return_address(0); \
269 if(((long)variable[0])&0x80000000) \
271 (variable)[1]=__builtin_return_address(1); \
272 if(((long)variable[1])&0x80000000) \
274 (variable)[2]=__builtin_return_address(2); \
275 if(((long)variable[2])&0x80000000) \
277 (variable)[3]=__builtin_return_address(3); \
278 if(((long)variable[3])&0x80000000) \
280 (variable)[4]=__builtin_return_address(4); \
281 if(((long)variable[4])&0x80000000) \
283 (variable)[5]=__builtin_return_address(5); \
284 if(((long)variable[5])&0x80000000) \
286 (variable)[6]=__builtin_return_address(6); \
287 if(((long)variable[6])&0x80000000) \
289 (variable)[7]=__builtin_return_address(7); \
290 if(((long)variable[7])&0x80000000) \
292 (variable)[8]=__builtin_return_address(8); \
293 if(((long)variable[8])&0x80000000) \
295 (variable)[9]=__builtin_return_address(9); \
306 #define CHANDEV_BACKTRACE(variable)
311 typedef struct chandev_not_oper_struct chandev_not_oper_struct;
313 struct chandev_not_oper_struct
315 chandev_not_oper_struct *next;
321 /* May as well try to keep machine checks in the order they happen so
322 * we use qheader for chandev_not_oper_head instead of list.
324 static qheader chandev_not_oper_head={NULL,NULL};
325 static spinlock_t chandev_not_oper_spinlock;
327 #define chandev_interrupt_check() \
329 printk(KERN_WARNING __FUNCTION__ " called under interrupt this shouldn't happen\n")
332 #define for_each(variable,head) \
333 for((variable)=(head);(variable)!=NULL;(variable)=(variable)->next)
335 #define for_each_allow_delete(variable,nextmember,head) \
336 for((variable)=(head),(nextmember)=((head) ? (head)->next:NULL); \
337 (variable)!=NULL; (variable)=(nextmember),(nextmember)=((nextmember) ? (nextmember->next) : NULL))
339 #define for_each_allow_delete2(variable,nextmember,head) \
340 for((variable)=(head);(variable)!=NULL;(variable)=(nextmember))
343 static void chandev_lock(void)
346 chandev_interrupt_check();
347 if(chandev_lock_owner!=(long)current)
349 while(!spin_trylock(&chandev_spinlock))
352 chandev_lock_owner=(long)current;
353 CHANDEV_BACKTRACE(chandev_first_lock_addr)
358 CHANDEV_BACKTRACE(chandev_last_lock_addr)
360 if(chandev_lock_cnt<0||chandev_lock_cnt>100)
362 printk("odd lock_cnt %d lcs_chan_lock",chandev_lock_cnt);
367 static int chandev_full_unlock(void)
369 int ret_lock_cnt=chandev_lock_cnt;
371 chandev_lock_owner=CHANDEV_INVALID_LOCK_OWNER;
372 spin_unlock(&chandev_spinlock);
373 return(ret_lock_cnt);
376 static void chandev_unlock(void)
378 if(chandev_lock_owner!=(long)current)
379 printk("chandev_unlock: current=%lx"
380 " chandev_lock_owner=%lx chandev_lock_cnt=%d\n",
384 CHANDEV_BACKTRACE(chandev_last_unlock_addr)
385 if(--chandev_lock_cnt==0)
387 chandev_lock_owner=CHANDEV_INVALID_LOCK_OWNER;
388 spin_unlock(&chandev_spinlock);
390 if(chandev_lock_cnt<0)
392 printk("odd lock_cnt=%d in chan_unlock",chandev_lock_cnt);
393 chandev_full_unlock();
400 void *chandev_alloc(size_t size)
402 void *mem=kmalloc(size,GFP_ATOMIC);
408 static void chandev_add_to_list(list **listhead,void *member)
411 add_to_list(listhead,member);
415 static void chandev_queuemember(qheader *qhead,void *member)
418 enqueue_tail(qhead,(queue *)member);
422 static int chandev_remove_from_list(list **listhead,list *member)
427 retval=remove_from_list(listhead,member);
432 static int chandev_remove_from_queue(qheader *qhead,queue *member)
437 retval=remove_from_queue(qhead,member);
444 void chandev_free_listmember(list **listhead,list *member)
449 if(chandev_remove_from_list(listhead,member))
452 printk(KERN_CRIT"chandev_free_listmember detected nonexistant"
453 "listmember listhead=%p member %p\n",listhead,member);
458 void chandev_free_queuemember(qheader *qhead,queue *member)
463 if(chandev_remove_from_queue(qhead,member))
466 printk(KERN_CRIT"chandev_free_queuemember detected nonexistant"
467 "queuemember qhead=%p member %p\n",qhead,member);
474 void chandev_free_all_list(list **listhead)
479 while((head=remove_listhead(listhead)))
484 void chandev_free_all_queue(qheader *qhead)
488 chandev_free_queuemember(qhead,qhead->head);
492 static void chandev_wait_for_root_fs(void)
494 wait_queue_head_t wait;
496 init_waitqueue_head(&wait);
497 /* We need to wait till there is a root filesystem */
498 while(init_task.fs->root==NULL)
500 sleep_on_timeout(&wait,HZ);
504 /* We are now hotplug compliant i.e. */
505 /* we typically get called in /sbin/hotplug chandev our parameters */
506 static int chandev_exec_start_script(void *unused)
509 char **argv,*tempname;
513 chandev_userland_notify_list *member;
514 wait_queue_head_t wait;
515 int have_tag[chandev_num_notify_tags]={FALSE,};
516 chandev_userland_notify_tag tagidx;
517 static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
519 init_waitqueue_head(&wait);
520 strcpy(current->comm,"chandev_script");
522 for(loopcnt=0;loopcnt<10&&(jiffies-chandev_last_startmsck_list_update)<HZ;loopcnt++)
524 sleep_on_timeout(&wait,HZ);
526 if(!chandev_userland_notify_head)
530 for(tagidx=chandev_first_tag;tagidx<chandev_num_notify_tags;tagidx++)
532 for_each(member,chandev_userland_notify_head)
534 if(member->tag==tagidx)
546 if(have_tag[tagidx]==FALSE)
548 have_tag[tagidx]=TRUE;
553 allocsize=(argc+1)*sizeof(char *);
554 /* Warning possible stack overflow */
555 /* We can't kmalloc the parameters here as execve will */
556 /* not return if successful */
557 argv=alloca(allocsize);
560 memset(argv,0,allocsize);
561 argv[0]=hotplug_path;
564 for(tagidx=chandev_first_tag;tagidx<chandev_num_notify_tags;tagidx++)
568 argv[argc++]=userland_notify_strs[tagidx];
569 for_each(member,chandev_userland_notify_head)
571 if(member->tag==tagidx)
573 tempname=alloca(strlen(member->devname)+1);
576 strcpy(tempname,member->devname);
577 argv[argc++]=tempname;
581 if(member->tag==chandev_msck)
583 argv[argc++]=msck_status_strs[member->prev_status];
584 argv[argc++]=msck_status_strs[member->curr_status];
590 chandev_free_all_list((list **)&chandev_userland_notify_head);
592 chandev_wait_for_root_fs();
593 /* We are basically execve'ing here there normally is no */
595 retval=exec_usermodehelper(hotplug_path, argv, envp);
606 void *chandev_allocstr(const char *str,size_t offset)
610 if((member=chandev_alloc(offset+strlen(str)+1)))
612 strcpy(&member[offset],str);
614 return((void *)member);
618 static int chandev_add_to_userland_notify_list(chandev_userland_notify_tag tag,
619 char *devname, chandev_msck_status prev_status,chandev_msck_status curr_status)
621 chandev_userland_notify_list *member,*nextmember;
625 /* remove operations still outstanding for this device */
626 for_each_allow_delete(member,nextmember,chandev_userland_notify_head)
627 if(strcmp(member->devname,devname)==0)
628 chandev_free_listmember((list **)&chandev_userland_notify_head,(list *)member);
631 if((member=chandev_allocstr(devname,offsetof(chandev_userland_notify_list,devname))))
634 member->prev_status=prev_status;
635 member->curr_status=curr_status;
636 add_to_list((list **)&chandev_userland_notify_head,(list *)member);
637 chandev_last_startmsck_list_update=jiffies;
639 pid = kernel_thread(chandev_exec_start_script,NULL,SIGCHLD);
642 printk("error making kernel thread for chandev_exec_start_script\n");
652 printk("chandev_add_to_startmscklist memory allocation failed devname=%s\n",devname);
661 int chandev_oper_func(int irq,devreg_t *dreg)
663 chandev_last_machine_check=jiffies;
664 if(atomic_dec_and_test(&chandev_msck_thread_lock))
666 schedule_task(&chandev_msck_task_tq);
668 atomic_set(&chandev_new_msck,TRUE);
672 static void chandev_not_oper_handler(int irq,int status )
674 chandev_not_oper_struct *new_not_oper;
676 chandev_last_machine_check=jiffies;
677 if((new_not_oper=kmalloc(sizeof(chandev_not_oper_struct),GFP_ATOMIC)))
679 new_not_oper->irq=irq;
680 new_not_oper->status=status;
681 spin_lock(&chandev_not_oper_spinlock);
682 enqueue_tail(&chandev_not_oper_head,(queue *)new_not_oper);
683 spin_unlock(&chandev_not_oper_spinlock);
684 if(atomic_dec_and_test(&chandev_msck_thread_lock))
686 schedule_task(&chandev_msck_task_tq);
690 printk("chandev_not_oper_handler failed to allocate memory & "
691 "lost a not operational interrupt %d %x",
695 chandev_irqinfo *chandev_get_irqinfo_by_irq(int irq)
697 chandev_irqinfo *curr_irqinfo;
698 for_each(curr_irqinfo,chandev_irqinfo_head)
699 if(irq==curr_irqinfo->sch.irq)
700 return(curr_irqinfo);
704 chandev *chandev_get_by_irq(int irq)
706 chandev *curr_chandev;
708 for_each(curr_chandev,(chandev *)chandev_head.head)
709 if(curr_chandev->sch.irq==irq)
711 return(curr_chandev);
716 chandev_activelist *chandev_get_activelist_by_irq(int irq)
718 chandev_activelist *curr_device;
720 for_each(curr_device,chandev_activelist_head)
722 if(curr_device->read_irqinfo->sch.irq==irq||
723 curr_device->write_irqinfo->sch.irq==irq||
724 (curr_device->data_irqinfo&&curr_device->data_irqinfo->sch.irq==irq))
731 void chandev_remove_irqinfo_by_irq(unsigned int irq)
733 chandev_irqinfo *remove_irqinfo;
734 chandev_activelist *curr_device;
737 /* remove any orphan irqinfo left lying around. */
738 if((remove_irqinfo=chandev_get_irqinfo_by_irq(irq)))
740 for_each(curr_device,chandev_activelist_head)
742 if(curr_device->read_irqinfo==remove_irqinfo)
744 curr_device->read_irqinfo=NULL;
747 if(curr_device->write_irqinfo==remove_irqinfo)
749 curr_device->write_irqinfo=NULL;
752 if(curr_device->data_irqinfo&&curr_device->data_irqinfo==remove_irqinfo)
754 curr_device->data_irqinfo=NULL;
758 chandev_free_listmember((list **)&chandev_irqinfo_head,
759 (list *)remove_irqinfo);
765 int chandev_add_schib_info(int irq,chandev_subchannel_info *sch)
769 if((new_schib=s390_get_schib(irq)))
771 sch->pim=new_schib->pmcw.pim;
772 memcpy(&sch->chpid,&new_schib->pmcw.chpid,sizeof(sch->chpid));
778 int chandev_request_irq(unsigned int irq,
779 void (*handler)(int, void *, struct pt_regs *),
780 unsigned long irqflags,
784 chandev_irqinfo *new_irqinfo;
785 chandev_activelist *curr_device;
786 s390_dev_info_t devinfo;
791 if((curr_device=chandev_get_activelist_by_irq(irq)))
793 printk("chandev_request_irq failed devname=%s irq=%d "
794 "it already belongs to %s shutdown this device first.\n",
795 devname,irq,curr_device->devname);
799 /* remove any orphan irqinfo left lying around. */
800 chandev_remove_irqinfo_by_irq(irq);
802 if((new_irqinfo=chandev_allocstr(devname,offsetof(chandev_irqinfo,devname))))
805 if((retval=get_dev_info_by_irq(irq,&devinfo))||
806 (retval=s390_request_irq_special(irq,handler,
807 chandev_not_oper_handler,
808 irqflags,devname,dev_id)))
812 new_irqinfo->msck_status=chandev_status_good;
813 new_irqinfo->sch.devno=devinfo.devno;
814 new_irqinfo->sch.irq=irq;
815 new_irqinfo->sch.cu_type=devinfo.sid_data.cu_type; /* control unit type */
816 new_irqinfo->sch.cu_model=devinfo.sid_data.cu_model; /* control unit model */
817 new_irqinfo->sch.dev_type=devinfo.sid_data.dev_type; /* device type */
818 new_irqinfo->sch.dev_model=devinfo.sid_data.dev_model; /* device model */
819 chandev_add_schib_info(irq,&new_irqinfo->sch);
820 new_irqinfo->handler=handler;
821 new_irqinfo->dev_id=dev_id;
822 chandev_add_to_list((list **)&chandev_irqinfo_head,new_irqinfo);
827 printk("chandev_request_irq memory allocation failed devname=%s irq=%d\n",devname,irq);
833 /* This should be safe to call even multiple times. */
834 void chandev_free_irq(unsigned int irq, void *dev_id)
836 s390_dev_info_t devinfo;
839 /* remove any orphan irqinfo left lying around. */
840 chandev_remove_irqinfo_by_irq(irq);
841 if((err=get_dev_info_by_irq(irq,&devinfo)))
843 printk("chandev_free_irq get_dev_info_by_irq reported err=%X on irq %d\n"
844 "should not happen\n",err,irq);
847 if(devinfo.status&DEVSTAT_DEVICE_OWNED)
848 free_irq(irq,dev_id);
851 /* This should be safe even if chandev_free_irq is already called by the device */
852 void chandev_free_irq_by_irqinfo(chandev_irqinfo *irqinfo)
855 chandev_free_irq(irqinfo->sch.irq,irqinfo->dev_id);
860 void chandev_sprint_type_model(char *buff,s32 type,s16 model)
865 sprintf(buff," 0x%04x ",(int)type);
870 sprintf(buff," 0x%02x ",(int)model);
873 void chandev_sprint_devinfo(char *buff,s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model)
875 chandev_sprint_type_model(buff,cu_type,cu_model);
876 chandev_sprint_type_model(&buff[strlen(buff)],dev_type,dev_model);
879 void chandev_remove_parms(chandev_type chan_type,int exact_match,int lo_devno)
881 chandev_parms *curr_parms,*next_parms;
884 for_each_allow_delete(curr_parms,next_parms,chandev_parms_head)
886 if(((chan_type&(curr_parms->chan_type)&&!exact_match)||
887 (chan_type==(curr_parms->chan_type)&&exact_match))&&
888 (lo_devno==-1||lo_devno==curr_parms->lo_devno))
889 chandev_free_listmember((list **)&chandev_parms_head,(list *)curr_parms);
895 void chandev_add_parms(chandev_type chan_type,u16 lo_devno,u16 hi_devno,char *parmstr)
897 chandev_parms *parms;
899 if(lo_devno>hi_devno)
901 printk("chandev_add_parms detected bad device range lo_devno=0x%04x hi_devno=0x%04x\n,",
902 (int)lo_devno,(int)hi_devno);
905 if((parms=chandev_allocstr(parmstr,offsetof(chandev_parms,parmstr))))
907 parms->chan_type=chan_type;
908 parms->lo_devno=lo_devno;
909 parms->hi_devno=hi_devno;
910 chandev_add_to_list((list **)&chandev_parms_head,(void *)parms);
913 printk("chandev_add_parms memory request failed\n");
917 void chandev_add_model(chandev_type chan_type,s32 cu_type,s16 cu_model,
918 s32 dev_type,s16 dev_model,u8 max_port_no,int auto_msck_recovery,
919 u8 default_checksum_received_ip_pkts,u8 default_use_hw_stats)
921 chandev_model_info *newmodel;
925 if((newmodel=chandev_alloc(sizeof(chandev_model_info))))
927 devreg_t *drinfo=&newmodel->drinfo;
928 newmodel->chan_type=chan_type;
929 newmodel->cu_type=cu_type;
930 newmodel->cu_model=cu_model;
931 newmodel->dev_type=dev_type;
932 newmodel->dev_model=dev_model;
933 newmodel->max_port_no=max_port_no;
934 newmodel->auto_msck_recovery=auto_msck_recovery;
935 newmodel->default_checksum_received_ip_pkts=default_checksum_received_ip_pkts;
936 newmodel->default_use_hw_stats=default_use_hw_stats; /* where available e.g. lcs */
937 if(cu_type==-1&&dev_type==-1)
939 chandev_sprint_devinfo(buff,newmodel->cu_type,newmodel->cu_model,
940 newmodel->dev_type,newmodel->dev_model);
941 printk(KERN_INFO"can't call s390_device_register for this device chan_type/chan_model/dev_type/dev_model %s\n",buff);
945 drinfo->flag=DEVREG_TYPE_DEVCHARS;
947 drinfo->flag|=DEVREG_MATCH_CU_TYPE;
949 drinfo->flag|=DEVREG_MATCH_CU_MODEL;
951 drinfo->flag|=DEVREG_MATCH_DEV_TYPE;
953 drinfo->flag|=DEVREG_MATCH_DEV_MODEL;
954 drinfo->ci.hc.ctype=cu_type;
955 drinfo->ci.hc.cmode=cu_model;
956 drinfo->ci.hc.dtype=dev_type;
957 drinfo->ci.hc.dmode=dev_model;
958 drinfo->oper_func=chandev_oper_func;
959 if((err=s390_device_register(&newmodel->drinfo)))
961 chandev_sprint_devinfo(buff,newmodel->cu_type,newmodel->cu_model,
962 newmodel->dev_type,newmodel->dev_model);
963 printk("s390_device_register failed in chandev_add_model"
964 " this is nothing to worry about chan_type/chan_model/dev_type/dev_model %s\n",buff);
965 drinfo->oper_func=NULL;
967 chandev_add_to_list((list **)&chandev_models_head,newmodel);
972 void chandev_remove(chandev *member)
974 chandev_free_queuemember(&chandev_head,(queue *)member);
978 void chandev_remove_all(void)
980 chandev_free_all_queue(&chandev_head);
983 void chandev_remove_model(chandev_model_info *model)
985 chandev *curr_chandev,*next_chandev;
988 for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)
989 if(curr_chandev->model_info==model)
990 chandev_remove(curr_chandev);
991 if(model->drinfo.oper_func)
992 s390_device_unregister(&model->drinfo);
993 chandev_free_listmember((list **)&chandev_models_head,(list *)model);
997 void chandev_remove_all_models(void)
1000 while(chandev_models_head)
1001 chandev_remove_model(chandev_models_head);
1005 void chandev_del_model(s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model)
1007 chandev_model_info *curr_model,*next_model;
1010 for_each_allow_delete(curr_model,next_model,chandev_models_head)
1011 if((curr_model->cu_type==cu_type||cu_type==-1)&&
1012 (curr_model->cu_model==cu_model||cu_model==-1)&&
1013 (curr_model->dev_type==dev_type||dev_type==-1)&&
1014 (curr_model->dev_model==dev_model||dev_model==-1))
1015 chandev_remove_model(curr_model);
1019 static void chandev_init_default_models(void)
1021 /* Usually P390/Planter 3172 emulation assume maximum 16 to be safe. */
1022 chandev_add_model(chandev_type_lcs,0x3088,0x1,-1,-1,15,default_msck_bits,FALSE,FALSE);
1024 /* 3172/2216 Paralell the 2216 allows 16 ports per card the */
1025 /* the original 3172 only allows 4 we will assume the max of 16 */
1026 chandev_add_model(chandev_type_lcs|chandev_type_ctc,0x3088,0x8,-1,-1,15,default_msck_bits,FALSE,FALSE);
1028 /* 3172/2216 Escon serial the 2216 allows 16 ports per card the */
1029 /* the original 3172 only allows 4 we will assume the max of 16 */
1030 chandev_add_model(chandev_type_lcs|chandev_type_escon,0x3088,0x1F,-1,-1,15,default_msck_bits,FALSE,FALSE);
1032 /* Only 2 ports allowed on OSA2 cards model 0x60 */
1033 chandev_add_model(chandev_type_lcs,0x3088,0x60,-1,-1,1,default_msck_bits,FALSE,FALSE);
1034 /* qeth gigabit ethernet */
1035 chandev_add_model(chandev_type_qeth,0x1731,0x1,0x1732,0x1,0,default_msck_bits,FALSE,FALSE);
1036 chandev_add_model(chandev_type_qeth,0x1731,0x5,0x1732,0x5,0,default_msck_bits,FALSE,FALSE);
1037 /* Osa-D we currently aren't too emotionally involved with this */
1038 chandev_add_model(chandev_type_osad,0x3088,0x62,-1,-1,0,default_msck_bits,FALSE,FALSE);
1040 chandev_add_model(chandev_type_claw,0x3088,0x61,-1,-1,0,default_msck_bits,FALSE,FALSE);
1042 /* ficon attached ctc */
1043 chandev_add_model(chandev_type_escon,0x3088,0x1E,-1,-1,0,default_msck_bits,FALSE,FALSE);
1047 void chandev_del_noauto(u16 devno)
1049 chandev_noauto_range *curr_noauto,*next_noauto;
1051 for_each_allow_delete(curr_noauto,next_noauto,chandev_noauto_head)
1052 if(curr_noauto->lo_devno<=devno&&curr_noauto->hi_devno>=devno)
1053 chandev_free_listmember((list **)&chandev_noauto_head,(list *)curr_noauto);
1057 void chandev_del_msck(u16 devno)
1059 chandev_msck_range *curr_msck_range,*next_msck_range;
1061 for_each_allow_delete(curr_msck_range,next_msck_range,chandev_msck_range_head)
1062 if(curr_msck_range->lo_devno<=devno&&curr_msck_range->hi_devno>=devno)
1063 chandev_free_listmember((list **)&chandev_msck_range_head,(list *)curr_msck_range);
1068 void chandev_add(s390_dev_info_t *newdevinfo,chandev_model_info *newmodelinfo)
1070 chandev *new_chandev=NULL;
1072 if((new_chandev=chandev_alloc(sizeof(chandev))))
1074 new_chandev->model_info=newmodelinfo;
1075 new_chandev->sch.devno=newdevinfo->devno;
1076 new_chandev->sch.irq=newdevinfo->irq;
1077 new_chandev->sch.cu_type=newdevinfo->sid_data.cu_type; /* control unit type */
1078 new_chandev->sch.cu_model=newdevinfo->sid_data.cu_model; /* control unit model */
1079 new_chandev->sch.dev_type=newdevinfo->sid_data.dev_type; /* device type */
1080 new_chandev->sch.dev_model=newdevinfo->sid_data.dev_model; /* device model */
1081 chandev_add_schib_info(newdevinfo->irq,&new_chandev->sch);
1082 new_chandev->owned=(newdevinfo->status&DEVSTAT_DEVICE_OWNED ? TRUE:FALSE);
1083 chandev_queuemember(&chandev_head,new_chandev);
1087 void chandev_unregister_probe(chandev_probefunc probefunc)
1089 chandev_probelist *curr_probe,*next_probe;
1092 for_each_allow_delete(curr_probe,next_probe,chandev_probelist_head)
1093 if(curr_probe->probefunc==probefunc)
1094 chandev_free_listmember((list **)&chandev_probelist_head,
1095 (list *)curr_probe);
1099 void chandev_unregister_probe_by_chan_type(chandev_type chan_type)
1101 chandev_probelist *curr_probe,*next_probe;
1104 for_each_allow_delete(curr_probe,next_probe,chandev_probelist_head)
1105 if(curr_probe->chan_type==chan_type)
1106 chandev_free_listmember((list **)&chandev_probelist_head,
1107 (list *)curr_probe);
1113 void chandev_reset(void)
1116 chandev_remove_all_models();
1117 chandev_free_all_list((list **)&chandev_noauto_head);
1118 chandev_free_all_list((list **)&chandev_msck_range_head);
1119 chandev_free_all_list((list **)&chandev_force_head);
1120 chandev_remove_parms(-1,FALSE,-1);
1121 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1122 chandev_use_devno_names=FALSE;
1124 chandev_persistent=0;
1129 int chandev_is_chandev(int irq,s390_dev_info_t *devinfo,chandev_force **forceinfo,chandev_model_info **ret_model)
1131 chandev_force *curr_force;
1132 chandev_model_info *curr_model=NULL;
1140 if((err=get_dev_info_by_irq(irq,devinfo)))
1142 printk("chandev_is_chandev get_dev_info_by_irq reported err=%X on irq %d\n"
1143 "should not happen\n",err,irq);
1148 for_each(curr_model,chandev_models_head)
1150 if(((curr_model->cu_type==devinfo->sid_data.cu_type)||(curr_model->cu_type==-1))&&
1151 ((curr_model->cu_model==devinfo->sid_data.cu_model)||(curr_model->cu_model==-1))&&
1152 ((curr_model->dev_type==devinfo->sid_data.dev_type)||(curr_model->dev_type==-1))&&
1153 ((curr_model->dev_model==devinfo->sid_data.dev_model)||(curr_model->dev_model==-1)))
1157 *ret_model=curr_model;
1161 for_each(curr_force,chandev_force_head)
1163 if(((curr_force->read_lo_devno==devinfo->devno)&&
1164 (curr_force->write_hi_devno==devinfo->devno)&&
1165 (curr_force->devif_num!=-2))||
1166 ((curr_force->read_lo_devno>=devinfo->devno)&&
1167 (curr_force->write_hi_devno<=devinfo->devno)&&
1168 (curr_force->devif_num==-2)))
1171 *forceinfo=curr_force;
1179 void chandev_collect_devices(void)
1181 int curr_irq,loopcnt=0;
1182 s390_dev_info_t curr_devinfo;
1183 chandev_model_info *curr_model;
1186 for(curr_irq=get_irq_first();curr_irq>=0; curr_irq=get_irq_next(curr_irq))
1188 /* check read chandev
1189 * we had to do the cu_model check also because ctc devices
1190 * have the same cutype & after asking some people
1191 * the model numbers are given out pseudo randomly so
1192 * we can't just take a range of them also the dev_type & models are 0
1197 printk(KERN_ERR"chandev_collect_devices detected infinite loop bug in get_irq_next\n");
1201 if(chandev_is_chandev(curr_irq,&curr_devinfo,NULL,&curr_model))
1202 chandev_add(&curr_devinfo,curr_model);
1207 int chandev_add_force(chandev_type chan_type,s32 devif_num,u16 read_lo_devno,
1208 u16 write_hi_devno,u16 data_devno,s32 memory_usage_in_k,s16 port_protocol_no,u8 checksum_received_ip_pkts,
1209 u8 use_hw_stats,char *host_name,char *adapter_name,char *api_type)
1211 chandev_force *new_chandev_force;
1213 if(devif_num==-2&&read_lo_devno>write_hi_devno)
1215 printk("chandev_add_force detected bad device range lo_devno=0x%04x hi_devno=0x%04x\n,",
1216 (int)read_lo_devno,(int)write_hi_devno);
1219 if(memory_usage_in_k<0)
1221 printk("chandev_add_force memory_usage_in_k is bad\n");
1224 if(chan_type==chandev_type_claw)
1226 int host_name_len=strlen(host_name),
1227 adapter_name_len=strlen(adapter_name),
1228 api_type_len=strlen(api_type);
1229 if(host_name_len>=CLAW_NAMELEN||host_name_len==0||
1230 adapter_name_len>=CLAW_NAMELEN||adapter_name_len==0||
1231 api_type_len>=CLAW_NAMELEN||api_type_len==0)
1234 if((new_chandev_force=chandev_alloc(sizeof(chandev_force))))
1236 new_chandev_force->chan_type=chan_type;
1237 new_chandev_force->devif_num=devif_num;
1238 new_chandev_force->read_lo_devno=read_lo_devno;
1239 new_chandev_force->write_hi_devno=write_hi_devno;
1240 new_chandev_force->data_devno=data_devno;
1241 new_chandev_force->memory_usage_in_k=memory_usage_in_k;
1242 new_chandev_force->port_protocol_no=port_protocol_no;
1243 new_chandev_force->checksum_received_ip_pkts=checksum_received_ip_pkts;
1244 new_chandev_force->use_hw_stats=use_hw_stats;
1246 if(chan_type==chandev_type_claw)
1248 strcpy(new_chandev_force->claw.host_name,host_name);
1249 strcpy(new_chandev_force->claw.adapter_name,adapter_name);
1250 strcpy(new_chandev_force->claw.api_type,api_type);
1252 chandev_add_to_list((list **)&chandev_force_head,new_chandev_force);
1257 void chandev_del_force(int read_lo_devno)
1259 chandev_force *curr_force,*next_force;
1262 for_each_allow_delete(curr_force,next_force,chandev_force_head)
1264 if(curr_force->read_lo_devno==read_lo_devno||read_lo_devno==-1)
1265 chandev_free_listmember((list **)&chandev_force_head,
1266 (list *)curr_force);
1272 void chandev_shutdown(chandev_activelist *curr_device)
1278 /* unregister_netdev calls the dev->close so we shouldn't do this */
1279 /* this otherwise we crash */
1280 if(curr_device->unreg_dev)
1282 curr_device->unreg_dev(curr_device->dev_ptr);
1283 curr_device->unreg_dev=NULL;
1285 if(curr_device->shutdownfunc)
1287 err=curr_device->shutdownfunc(curr_device->dev_ptr);
1290 printk("chandev_shutdown unable to fully shutdown & unload %s err=%d\n"
1291 "probably some upper layer still requires the device to exist\n",
1292 curr_device->devname,err);
1296 chandev_free_irq_by_irqinfo(curr_device->read_irqinfo);
1297 chandev_free_irq_by_irqinfo(curr_device->write_irqinfo);
1298 if(curr_device->data_irqinfo)
1299 chandev_free_irq_by_irqinfo(curr_device->data_irqinfo);
1300 chandev_free_listmember((list **)&chandev_activelist_head,
1301 (list *)curr_device);
1306 void chandev_shutdown_all(void)
1308 while(chandev_activelist_head)
1309 chandev_shutdown(chandev_activelist_head);
1311 void chandev_shutdown_by_name(char *devname)
1313 chandev_activelist *curr_device;
1316 for_each(curr_device,chandev_activelist_head)
1317 if(strcmp(devname,curr_device->devname)==0)
1319 chandev_shutdown(curr_device);
1325 static chandev_activelist *chandev_active(u16 devno)
1327 chandev_activelist *curr_device;
1329 for_each(curr_device,chandev_activelist_head)
1330 if(curr_device->read_irqinfo->sch.devno==devno||
1331 curr_device->write_irqinfo->sch.devno==devno||
1332 (curr_device->data_irqinfo&&curr_device->data_irqinfo->sch.devno==devno))
1334 return(curr_device);
1339 void chandev_shutdown_by_devno(u16 devno)
1341 chandev_activelist *curr_device;
1344 curr_device=chandev_active(devno);
1346 chandev_shutdown(curr_device);
1351 int chandev_pack_args(char *str)
1353 char *newstr=str,*next;
1359 /*remove dead spaces */
1360 if(isspace(*str)&&isspace(*next))
1370 if(((*str)==';')&&(*next))
1391 chandev_strval chandev_strcmp(char *teststr,char **str,long *endlong)
1394 chandev_strval retval=isnull;
1396 int len=strlen(teststr);
1397 if(strncmp(teststr,*str,len)==0)
1402 *endlong=simple_strtol(cur,str,0);
1417 int chandev_initdevice(chandev_probeinfo *probeinfo,void *dev_ptr,u8 port_no,char *devname,chandev_category category,chandev_unregfunc unreg_dev)
1419 chandev_activelist *newdevice,*curr_device;
1421 chandev_interrupt_check();
1422 if(probeinfo->newdevice!=NULL)
1424 printk("probeinfo->newdevice!=NULL in chandev_initdevice for %s",devname);
1430 for_each(curr_device,chandev_activelist_head)
1432 if(strcmp(curr_device->devname,devname)==0)
1434 printk("chandev_initdevice detected duplicate devicename %s\n",devname);
1439 if((newdevice=chandev_allocstr(devname,offsetof(chandev_activelist,devname))))
1441 newdevice->read_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->read.irq);
1442 newdevice->write_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->write.irq);
1443 if(probeinfo->data_exists)
1444 newdevice->data_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->data.irq);
1446 if(newdevice->read_irqinfo==NULL||newdevice->write_irqinfo==NULL||
1447 (probeinfo->data_exists&&newdevice->data_irqinfo==NULL))
1449 printk("chandev_initdevice, it appears that chandev_request_irq was not "
1450 "called for devname=%s read_irq=%d write_irq=%d data_irq=%d\n",
1451 devname,probeinfo->read.irq,probeinfo->write.irq,probeinfo->data.irq);
1455 newdevice->chan_type=probeinfo->chan_type;
1456 newdevice->dev_ptr=dev_ptr;
1457 newdevice->port_no=port_no;
1458 newdevice->memory_usage_in_k=probeinfo->memory_usage_in_k;
1459 newdevice->category=category;
1460 newdevice->unreg_dev=unreg_dev;
1461 probeinfo->newdevice=newdevice;
1469 char *chandev_build_device_name(chandev_probeinfo *probeinfo,char *destnamebuff,char *basename,int buildfullname)
1471 if (chandev_use_devno_names&&(!probeinfo->device_forced||probeinfo->devif_num==-1))
1472 sprintf(destnamebuff,"%s%04x",basename,(int)probeinfo->read.devno);
1475 if(probeinfo->devif_num==-1)
1479 int idx,len=strlen(basename);
1481 chandev_activelist *curr_device;
1482 for(idx=0;idx<0xffff;idx++)
1484 for_each(curr_device,chandev_activelist_head)
1486 if(strncmp(curr_device->devname,basename,len)==0)
1489 sprintf(numbuff,"%d",idx);
1490 if(strcmp(&curr_device->devname[len],numbuff)==0)
1494 sprintf(destnamebuff,"%s%d",basename,idx);
1495 return(destnamebuff);
1498 printk("chandev_build_device_name was usable to build a unique name for %s\n",basename);
1502 sprintf(destnamebuff,"%s%%d",basename);
1506 sprintf(destnamebuff,"%s%d",basename,(int)probeinfo->devif_num);
1509 return(destnamebuff);
1512 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1513 struct net_device *chandev_init_netdev(chandev_probeinfo *probeinfo,char *basename,
1514 struct net_device *dev, int sizeof_priv,
1515 struct net_device *(*init_netdevfunc)(struct net_device *dev, int sizeof_priv))
1517 struct device *chandev_init_netdev(chandev_probeinfo *probeinfo,char *basename,
1518 struct device *dev, int sizeof_priv,
1519 struct device *(*init_netdevfunc)(struct device *dev, int sizeof_priv))
1522 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1523 struct net_device *retdevice=NULL;
1524 int new_device = FALSE;
1526 struct device *retdevice=NULL;
1530 chandev_interrupt_check();
1531 if (!init_netdevfunc)
1533 printk("init_netdevfunc=NULL in chandev_init_netdev, it should not be valid.\n");
1536 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1537 /* Allocate a device if one is not provided. */
1540 /* ensure 32-byte alignment of the private area */
1541 int alloc_size = sizeof (*dev) + sizeof_priv + 31;
1543 dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
1546 printk(KERN_ERR "chandev_initnetdevice: Unable to allocate device memory.\n");
1550 memset(dev, 0, alloc_size);
1553 dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
1556 chandev_build_device_name(probeinfo,dev->name,basename,FALSE);
1558 retdevice=init_netdevfunc(dev,sizeof_priv);
1559 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1560 /* Register device if necessary */
1561 /* we need to do this as init_netdev doesn't call register_netdevice */
1562 /* for already allocated devices */
1563 if (retdevice && new_device)
1564 register_netdev(retdevice);
1566 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1567 /* We allocated it, so we should free it on error */
1568 if (!retdevice && new_device)
1577 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1578 struct net_device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
1579 struct net_device *dev, int sizeof_priv, char *basename,
1580 struct net_device *(*init_netdevfunc)(struct net_device *dev, int sizeof_priv),
1581 void (*unreg_netdevfunc)(struct net_device *dev))
1583 struct device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
1584 struct device *dev, int sizeof_priv, char *basename,
1585 struct device *(*init_netdevfunc)(struct device *dev, int sizeof_priv),
1586 void (*unreg_netdevfunc)(struct device *dev))
1589 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1590 struct net_device *retdevice=NULL;
1591 int new_device=(dev==NULL);
1593 struct device *retdevice=NULL;
1596 if (!unreg_netdevfunc)
1598 printk("unreg_netdevfunc=NULL in chandev_initnetdevice, it should not be valid.\n");
1601 chandev_interrupt_check();
1602 retdevice=chandev_init_netdev(probeinfo,basename,dev,sizeof_priv,init_netdevfunc);
1605 if (chandev_initdevice(probeinfo,retdevice,port_no,retdevice->name,
1606 chandev_category_network_device,(chandev_unregfunc)unreg_netdevfunc))
1608 unreg_netdevfunc(retdevice);
1609 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1610 /* We allocated it, so we should free it on error */
1622 int chandev_compare_chpid_info(chandev_subchannel_info *chan1,chandev_subchannel_info *chan2)
1624 return (chan1->pim!=chan2->pim || *chan1->chpid!=*chan2->chpid);
1627 int chandev_compare_cu_dev_info(chandev_subchannel_info *chan1,chandev_subchannel_info *chan2)
1629 return ((chan1->cu_type != chan2->cu_type)||
1630 (chan1->cu_model != chan2->cu_model)||
1631 (chan1->dev_type != chan2->dev_type)||
1632 (chan1->dev_model != chan2->dev_model));
1635 int chandev_compare_subchannel_info(chandev_subchannel_info *chan1,chandev_subchannel_info *chan2)
1637 return((chan1->devno == chan2->devno) &&
1638 (chan1->cu_type == chan2->cu_type) &&
1639 (chan1->cu_model == chan2->cu_model) &&
1640 (chan1->dev_type == chan2->dev_type) &&
1641 (chan1->dev_model == chan2->dev_model) &&
1642 (chan1->pim == chan2->pim) &&
1643 (*chan1->chpid == *chan2->chpid));
1647 int chandev_doprobe(chandev_force *force,chandev *read,
1648 chandev *write,chandev *data)
1650 chandev_probelist *probe;
1651 chandev_model_info *model_info;
1652 chandev_probeinfo probeinfo;
1654 chandev_activelist *newdevice;
1655 chandev_probefunc probefunc;
1656 chandev_parms *curr_parms;
1657 chandev_model_info dummy_model_info;
1659 memset(&probeinfo,0,sizeof(probeinfo));
1660 memset(&dummy_model_info,0,sizeof(dummy_model_info));
1661 probeinfo.device_forced=(force!=NULL);
1662 probeinfo.chpid_info_inconsistent=chandev_compare_chpid_info(&read->sch,&write->sch)||
1663 (data&&chandev_compare_chpid_info(&read->sch,&data->sch));
1664 probeinfo.cu_dev_info_inconsistent=chandev_compare_cu_dev_info(&read->sch,&write->sch)||
1665 (data&&chandev_compare_cu_dev_info(&read->sch,&data->sch));
1666 if(read->model_info)
1667 model_info=read->model_info;
1670 dummy_model_info.chan_type=chandev_type_none;
1671 dummy_model_info.max_port_no=16;
1672 model_info=&dummy_model_info;
1674 for_each(probe,chandev_probelist_head)
1677 probeinfo.chan_type = ( probe->chan_type & force->chan_type );
1680 if(chandev_cautious_auto_detect)
1681 probeinfo.chan_type = ( probe->chan_type == model_info->chan_type ?
1682 probe->chan_type : chandev_type_none );
1684 probeinfo.chan_type = ( probe->chan_type & model_info->chan_type );
1686 if(probeinfo.chan_type && (force || ( !probeinfo.cu_dev_info_inconsistent &&
1687 ((probe->chan_type&(chandev_type_ctc|chandev_type_escon)) ||
1688 !probeinfo.chpid_info_inconsistent))))
1690 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
1691 if(chandev_use_devno_names)
1692 probeinfo.devif_num=read->sch.devno;
1695 probeinfo.devif_num=-1;
1696 probeinfo.read=read->sch;
1697 probeinfo.write=write->sch;
1700 probeinfo.data=data->sch;
1701 probeinfo.data_exists=TRUE;
1703 probeinfo.max_port_no=(force&&(force->port_protocol_no!=-1) ?
1704 force->port_protocol_no : model_info->max_port_no);
1705 for_each(curr_parms,chandev_parms_head)
1707 if(probe->chan_type==curr_parms->chan_type&&
1708 read->sch.devno>=curr_parms->lo_devno&&
1709 read->sch.devno<=curr_parms->hi_devno)
1711 if (!probeinfo.parmstr) {
1712 probeinfo.parmstr = vmalloc(sizeof(curr_parms->parmstr)+1);
1713 strcpy(probeinfo.parmstr, curr_parms->parmstr);
1717 buf = vmalloc(strlen(probeinfo.parmstr)+strlen(curr_parms->parmstr)+2);
1718 sprintf(buf, "%s,%s",probeinfo.parmstr, curr_parms->parmstr);
1719 probeinfo.parmstr=buf;
1725 if(force->chan_type==chandev_type_claw)
1726 memcpy(&probeinfo.claw,&force->claw,sizeof(chandev_claw_info));
1727 probeinfo.port_protocol_no=force->port_protocol_no;
1728 if(force->devif_num==-1&&force->devif_num==-2)
1729 probeinfo.devif_num=-1;
1731 probeinfo.devif_num=force->devif_num;
1732 probeinfo.memory_usage_in_k=force->memory_usage_in_k;
1733 probeinfo.checksum_received_ip_pkts=force->checksum_received_ip_pkts;
1734 probeinfo.use_hw_stats=force->use_hw_stats;
1738 probeinfo.port_protocol_no=0;
1739 probeinfo.checksum_received_ip_pkts=model_info->default_checksum_received_ip_pkts;
1740 probeinfo.use_hw_stats=model_info->default_use_hw_stats;
1741 probeinfo.memory_usage_in_k=0;
1742 if(probe->chan_type&chandev_type_lcs)
1744 hint=(read->sch.devno&0xFF)>>1;
1745 if(hint>model_info->max_port_no)
1747 /* The card is possibly emulated e.g P/390 */
1748 /* or possibly configured to use a shared */
1749 /* port configured by osa-sf. */
1754 probeinfo.hint_port_no=hint;
1755 probefunc=probe->probefunc;
1756 rc=probefunc(&probeinfo);
1759 newdevice=probeinfo.newdevice;
1762 newdevice->probefunc=probe->probefunc;
1763 newdevice->shutdownfunc=probe->shutdownfunc;
1764 newdevice->msck_notfunc=probe->msck_notfunc;
1765 probe->devices_found++;
1766 chandev_add_to_list((list **)&chandev_activelist_head,
1768 chandev_add_to_userland_notify_list(chandev_start,
1769 newdevice->devname,chandev_status_good,chandev_status_good);
1773 printk("chandev_initdevice either failed or wasn't called for device read_irq=0x%04x\n",probeinfo.read.irq);
1780 chandev_remove(read);
1781 chandev_remove(write);
1783 chandev_remove(data);
1788 int chandev_request_irq_from_irqinfo(chandev_irqinfo *irqinfo,chandev *this_chandev)
1790 int retval=s390_request_irq_special(irqinfo->sch.irq,
1792 chandev_not_oper_handler,
1798 irqinfo->msck_status=chandev_status_good;
1799 this_chandev->owned=TRUE;
1804 void chandev_irqallocerr(chandev_irqinfo *irqinfo,int err)
1806 printk("chandev_probe failed to realloc irq=%d for %s err=%d\n",irqinfo->sch.irq,irqinfo->devname,err);
1810 void chandev_call_notification_func(chandev_activelist *curr_device,chandev_irqinfo *curr_irqinfo,
1811 chandev_msck_status prevstatus)
1813 if(curr_irqinfo->msck_status!=prevstatus)
1815 chandev_msck_status new_msck_status=curr_irqinfo->msck_status;
1816 if(curr_irqinfo->msck_status==chandev_status_good)
1818 if(curr_device->read_irqinfo->msck_status==chandev_status_good&&
1819 curr_device->write_irqinfo->msck_status==chandev_status_good)
1821 if(curr_device->data_irqinfo)
1823 if(curr_device->data_irqinfo->msck_status==chandev_status_good)
1824 new_msck_status=chandev_status_all_chans_good;
1827 new_msck_status=chandev_status_all_chans_good;
1830 if(curr_device->msck_notfunc)
1832 curr_device->msck_notfunc(curr_device->dev_ptr,
1833 curr_irqinfo->sch.irq,
1834 prevstatus,new_msck_status);
1836 if(new_msck_status!=chandev_status_good)
1838 /* No point in sending a machine check if only one channel is good */
1839 chandev_add_to_userland_notify_list(chandev_msck,curr_device->devname,
1840 prevstatus,curr_irqinfo->msck_status);
1845 int chandev_find_eligible_channels(chandev *first_chandev_to_check,
1846 chandev **read,chandev **write,chandev **data,chandev **next,
1847 chandev_type chan_type)
1849 chandev *curr_chandev;
1850 int eligible_found=FALSE,changed;
1852 *next=first_chandev_to_check->next;
1853 *read=*write=*data=NULL;
1854 for_each(curr_chandev,first_chandev_to_check)
1855 if((curr_chandev->sch.devno&1)==0&&curr_chandev->model_info->chan_type!=chandev_type_claw)
1858 if(chan_type==chandev_type_none)
1859 chan_type=(*read)->model_info->chan_type;
1864 for_each(curr_chandev,(chandev *)chandev_head.head)
1865 if((((*read)->sch.devno|1)==curr_chandev->sch.devno)&&
1866 (chandev_compare_cu_dev_info(&(*read)->sch,&curr_chandev->sch)==0)&&
1867 ((chan_type&(chandev_type_ctc|chandev_type_escon))||
1868 chandev_compare_chpid_info(&(*read)->sch,&curr_chandev->sch)==0))
1870 *write=curr_chandev;
1874 if((chan_type&chandev_type_qeth))
1878 for_each(curr_chandev,(chandev *)chandev_head.head)
1879 if((curr_chandev!=*read&&curr_chandev!=*write)&&
1880 (chandev_compare_cu_dev_info(&(*read)->sch,&curr_chandev->sch)==0)&&
1881 (chandev_compare_chpid_info(&(*read)->sch,&curr_chandev->sch)==0))
1887 eligible_found=TRUE;
1893 eligible_found=TRUE;
1900 ((*read&&(*read==*next))||
1901 (*write&&(*write==*next))||
1902 (*data&&(*data==*next))))
1904 *next=(*next)->next;
1907 }while(changed==TRUE);
1909 return(eligible_found);
1912 chandev *chandev_get_free_chandev_by_devno(int devno)
1914 chandev *curr_chandev;
1917 for_each(curr_chandev,(chandev *)chandev_head.head)
1918 if(curr_chandev->sch.devno==devno)
1920 if(chandev_active(devno))
1923 return(curr_chandev);
1929 void chandev_probe(void)
1931 chandev *read_chandev,*write_chandev,*data_chandev,*curr_chandev,*next_chandev;
1932 chandev_force *curr_force;
1933 chandev_noauto_range *curr_noauto;
1934 chandev_activelist *curr_device;
1935 chandev_irqinfo *curr_irqinfo;
1936 s390_dev_info_t curr_devinfo;
1938 int auto_msck_recovery;
1939 chandev_msck_status prevstatus;
1940 chandev_msck_range *curr_msck_range;
1943 chandev_interrupt_check();
1944 chandev_read_conf_if_necessary();
1945 chandev_collect_devices();
1947 for_each(curr_irqinfo,chandev_irqinfo_head)
1949 if((curr_device=chandev_get_activelist_by_irq(curr_irqinfo->sch.irq)))
1951 prevstatus=curr_irqinfo->msck_status;
1952 if(curr_irqinfo->msck_status!=chandev_status_good)
1954 curr_chandev=chandev_get_by_irq(curr_irqinfo->sch.irq);
1957 auto_msck_recovery=curr_chandev->model_info->
1962 for_each(curr_msck_range,chandev_msck_range_head)
1964 if(curr_msck_range->lo_devno<=
1965 curr_irqinfo->sch.devno&&
1966 curr_msck_range->hi_devno>=
1967 curr_irqinfo->sch.devno)
1975 if((1<<(curr_irqinfo->msck_status-1))&auto_msck_recovery)
1977 if(curr_irqinfo->msck_status==chandev_status_revalidate)
1979 if((get_dev_info_by_irq(curr_irqinfo->sch.irq,&curr_devinfo)==0))
1981 curr_irqinfo->sch.devno=curr_devinfo.devno;
1982 curr_irqinfo->msck_status=chandev_status_good;
1989 /* Has the device reappeared */
1990 if(chandev_compare_subchannel_info(
1992 &curr_device->read_irqinfo->sch)||
1993 chandev_compare_subchannel_info(
1995 &curr_device->write_irqinfo->sch)||
1996 (curr_device->data_irqinfo&&
1997 chandev_compare_subchannel_info(
1999 &curr_device->data_irqinfo->sch)))
2001 if((err=chandev_request_irq_from_irqinfo(curr_irqinfo,curr_chandev))==0)
2002 curr_irqinfo->msck_status=chandev_status_good;
2004 chandev_irqallocerr(curr_irqinfo,err);
2011 chandev_call_notification_func(curr_device,curr_irqinfo,prevstatus);
2013 /* This is required because the device can go & come back */
2014 /* even before we realize it is gone owing to the waits in our kernel threads */
2015 /* & the device will be marked as not owned but its status will be good */
2016 /* & an attempt to accidently reprobe it may be done. */
2018 chandev_remove(chandev_get_by_irq(curr_irqinfo->sch.irq));
2022 for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)
2023 if(curr_chandev->owned)
2024 chandev_remove(curr_chandev);
2025 for_each(curr_force,chandev_force_head)
2027 if(curr_force->devif_num==-2)
2029 for_each_allow_delete2(curr_chandev,next_chandev,(chandev *)chandev_head.head)
2031 if(chandev_find_eligible_channels(curr_chandev,&read_chandev,
2032 &write_chandev,&data_chandev,
2034 curr_force->chan_type));
2036 if((curr_force->read_lo_devno>=read_chandev->sch.devno)&&
2037 (curr_force->write_hi_devno<=read_chandev->sch.devno)&&
2038 (curr_force->read_lo_devno>=write_chandev->sch.devno)&&
2039 (curr_force->write_hi_devno<=write_chandev->sch.devno)&&
2040 (!data_chandev||(data_chandev&&
2041 (curr_force->read_lo_devno>=data_chandev->sch.devno)&&
2042 (curr_force->write_hi_devno<=data_chandev->sch.devno))))
2043 chandev_doprobe(curr_force,read_chandev,write_chandev,
2050 read_chandev=chandev_get_free_chandev_by_devno(curr_force->read_lo_devno);
2053 write_chandev=chandev_get_free_chandev_by_devno(curr_force->write_hi_devno);
2056 if(curr_force->chan_type==chandev_type_qeth)
2059 data_chandev=chandev_get_free_chandev_by_devno(curr_force->data_devno);
2060 if(data_chandev==NULL)
2061 printk("chandev_probe unable to force gigabit_ethernet driver invalid device no 0x%04x given\n",curr_force->data_devno);
2065 chandev_doprobe(curr_force,read_chandev,write_chandev,
2071 for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)
2073 for_each(curr_noauto,chandev_noauto_head)
2075 if(curr_chandev->sch.devno>=curr_noauto->lo_devno&&
2076 curr_chandev->sch.devno<=curr_noauto->hi_devno)
2078 chandev_remove(curr_chandev);
2083 for_each_allow_delete2(curr_chandev,next_chandev,(chandev *)chandev_head.head)
2085 if(chandev_find_eligible_channels(curr_chandev,&read_chandev,
2086 &write_chandev,&data_chandev,
2089 chandev_doprobe(NULL,read_chandev,write_chandev,
2092 chandev_remove_all();
2096 static void chandev_not_oper_func(int irq,int status)
2098 chandev_irqinfo *curr_irqinfo;
2099 chandev_activelist *curr_device;
2102 for_each(curr_irqinfo,chandev_irqinfo_head)
2103 if(curr_irqinfo->sch.irq==irq)
2105 chandev_msck_status prevstatus=curr_irqinfo->msck_status;
2108 /* Currently defined but not used in kernel */
2109 /* Despite being in specs */
2110 case DEVSTAT_NOT_OPER:
2111 curr_irqinfo->msck_status=chandev_status_not_oper;
2113 #ifdef DEVSTAT_NO_PATH
2114 /* Kernel hasn't this defined currently. */
2115 /* Despite being in specs */
2116 case DEVSTAT_NO_PATH:
2117 curr_irqinfo->msck_status=chandev_status_no_path;
2120 case DEVSTAT_REVALIDATE:
2121 curr_irqinfo->msck_status=chandev_status_revalidate;
2123 case DEVSTAT_DEVICE_GONE:
2124 curr_irqinfo->msck_status=chandev_status_gone;
2127 if((curr_device=chandev_get_activelist_by_irq(irq)))
2128 chandev_call_notification_func(curr_device,curr_irqinfo,prevstatus);
2130 printk("chandev_not_oper_func received channel check for unowned irq %d",irq);
2136 static int chandev_msck_thread(void *unused)
2138 int loopcnt,not_oper_probe_required=FALSE;
2139 wait_queue_head_t wait;
2140 chandev_not_oper_struct *new_not_oper;
2142 /* This loop exists because machine checks tend to come in groups & we have
2143 to wait for the other devnos to appear also */
2144 init_waitqueue_head(&wait);
2145 for(loopcnt=0;loopcnt<10||(jiffies-chandev_last_machine_check)<HZ;loopcnt++)
2147 sleep_on_timeout(&wait,HZ);
2149 atomic_set(&chandev_msck_thread_lock,1);
2150 while(!atomic_compare_and_swap(TRUE,FALSE,&chandev_new_msck));
2157 unsigned long flags;
2158 spin_lock_irqsave(&chandev_not_oper_spinlock,flags);
2159 new_not_oper=(chandev_not_oper_struct *)dequeue_head(&chandev_not_oper_head);
2160 spin_unlock_irqrestore(&chandev_not_oper_spinlock,flags);
2163 chandev_not_oper_func(new_not_oper->irq,new_not_oper->status);
2164 not_oper_probe_required=TRUE;
2165 kfree(new_not_oper);
2170 if(not_oper_probe_required)
2175 static void chandev_msck_task(void *unused)
2177 if(kernel_thread(chandev_msck_thread,NULL,SIGCHLD)<0)
2179 atomic_set(&chandev_msck_thread_lock,1);
2180 printk("error making chandev_msck_thread kernel thread\n");
2186 static char *argstrs[]=
2199 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
2201 "dont_use_devno_names",
2203 "cautious_auto_detect",
2204 "non_cautious_auto_detect",
2215 "unregister_probe_by_chan_type",
2225 noauto_stridx=first_stridx,
2236 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
2237 use_devno_names_stridx,
2238 dont_use_devno_names_stridx,
2240 cautious_auto_detect_stridx,
2241 non_cautious_auto_detect_stridx,
2245 del_auto_msck_stridx,
2246 del_all_models_stridx,
2247 reset_conf_clean_stridx,
2251 unregister_probe_stridx,
2252 unregister_probe_by_chan_type_stridx,
2254 dont_read_conf_stridx,
2259 void chandev_add_noauto(u16 lo_devno,u16 hi_devno)
2261 chandev_noauto_range *new_range;
2263 if((new_range=chandev_alloc(sizeof(chandev_noauto_range))))
2265 new_range->lo_devno=lo_devno;
2266 new_range->hi_devno=hi_devno;
2267 chandev_add_to_list((list **)&chandev_noauto_head,new_range);
2272 void chandev_add_msck_range(u16 lo_devno,u16 hi_devno,int auto_msck_recovery)
2274 chandev_msck_range *new_range;
2276 if((new_range=chandev_alloc(sizeof(chandev_msck_range))))
2278 new_range->lo_devno=lo_devno;
2279 new_range->hi_devno=hi_devno;
2280 new_range->auto_msck_recovery=auto_msck_recovery;
2281 chandev_add_to_list((list **)&chandev_msck_range_head,new_range);
2287 static char chandev_keydescript[]=
2288 "\nchan_type key bitfield ctc=0x1,escon=0x2,lcs=0x4,osad=0x8,qeth=0x10,claw=0x20\n";
2291 #if CONFIG_ARCH_S390X
2292 /* We need this as we sometimes use this to evaluate pointers */
2293 typedef long chandev_int;
2295 typedef int chandev_int;
2299 #if (LINUX_VERSION_CODE<KERNEL_VERSION(2,3,0)) || (CONFIG_ARCH_S390X)
2301 * Read an int from an option string; if available accept a subsequent
2305 * 0 : no int in string
2306 * 1 : int found, no subsequent comma
2307 * 2 : int found including a subsequent comma
2309 static chandev_int chandev_get_option(char **str,chandev_int *pint)
2313 if (!cur || !(*cur)) return 0;
2314 *pint = simple_strtol(cur,str,0);
2315 if (cur==*str) return 0;
2325 static char *chandev_get_options(char *str, int nints, chandev_int *ints)
2331 res = chandev_get_option(&str, ints+i);
2340 #define chandev_get_option get_option
2341 #define chandev_get_options get_options
2344 * Read an string from an option string; if available accept a subsequent
2345 * comma as well & set this comma to a null character when returning the string.
2348 * 0 : no string found
2349 * 1 : string found, no subsequent comma
2350 * 2 : string found including a subsequent comma
2352 static int chandev_get_string(char **instr,char **outstr)
2381 static int chandev_setup(int in_read_conf,char *instr,char *errstr,int lineno)
2383 chandev_strval val=isnull;
2384 chandev_str_enum stridx;
2386 chandev_type chan_type;
2387 char *str,*currstr,*interpretstr=NULL;
2390 #define CHANDEV_MAX_EXTRA_INTS 12
2391 chandev_int ints[CHANDEV_MAX_EXTRA_INTS+1];
2392 currstr=alloca(strlen(instr)+1);
2393 strcpy(currstr,instr);
2394 strcnt=chandev_pack_args(currstr);
2395 for(cnt=1;cnt<=strcnt;cnt++)
2397 interpretstr=currstr;
2398 memset(ints,0,sizeof(ints));
2399 for(stridx=first_stridx;stridx<last_stridx;stridx++)
2402 if((val=chandev_strcmp(argstrs[stridx],&str,&endlong)))
2408 val=(((chandev_strval)stridx)*stridx_mult)+(val&~isstr);
2411 case (add_parms_stridx*stridx_mult)|iscomma:
2412 currstr=chandev_get_options(currstr,4,ints);
2413 if(*currstr&&ints[0]>=1)
2422 chandev_add_parms(ints[1],ints[2],ints[3],currstr);
2428 case (claw_stridx*stridx_mult)|isnum|iscomma:
2429 case (claw_stridx*stridx_mult)|iscomma:
2430 currstr=chandev_get_options(str,6,ints);
2434 currstr=chandev_get_options(str,CHANDEV_MAX_EXTRA_INTS,ints);
2439 case noauto_stridx*stridx_mult:
2440 case (noauto_stridx*stridx_mult)|iscomma:
2444 chandev_free_all_list((list **)&chandev_noauto_head);
2445 chandev_add_noauto(0,0xffff);
2450 chandev_add_noauto(ints[1],ints[2]);
2456 case (auto_msck_stridx*stridx_mult)|iscomma:
2460 chandev_free_all_list((list **)&chandev_msck_range_head);
2461 chandev_add_msck_range(0,0xffff,ints[1]);
2464 chandev_add_msck_range(ints[1],ints[1],ints[2]);
2467 chandev_add_msck_range(ints[1],ints[2],ints[3]);
2474 case del_auto_msck_stridx*stridx_mult:
2475 case (del_auto_msck_stridx*stridx_mult)|iscomma:
2479 chandev_free_all_list((list **)&chandev_msck_range_head);
2482 chandev_del_msck(ints[1]);
2487 case del_noauto_stridx*stridx_mult:
2488 chandev_free_all_list((list **)&chandev_noauto_head);
2490 case (del_noauto_stridx*stridx_mult)|iscomma:
2492 chandev_del_noauto(ints[1]);
2496 case (qeth_stridx*stridx_mult)|isnum|iscomma:
2497 if(ints[0]<3||ints[0]>7)
2499 chandev_add_force(chandev_type_qeth,endlong,ints[1],ints[2],
2500 ints[3],ints[4],ints[5],ints[6],ints[7],
2503 case (ctc_stridx*stridx_mult)|isnum|iscomma:
2504 case (escon_stridx*stridx_mult)|isnum|iscomma:
2505 case (lcs_stridx*stridx_mult)|isnum|iscomma:
2506 case (osad_stridx*stridx_mult)|isnum|iscomma:
2507 case (ctc_stridx*stridx_mult)|iscomma:
2508 case (escon_stridx*stridx_mult)|iscomma:
2509 case (lcs_stridx*stridx_mult)|iscomma:
2510 case (osad_stridx*stridx_mult)|iscomma:
2511 switch(val&~(isnum|iscomma))
2513 case (ctc_stridx*stridx_mult):
2514 chan_type=chandev_type_ctc;
2516 case (escon_stridx*stridx_mult):
2517 chan_type=chandev_type_escon;
2519 case (lcs_stridx*stridx_mult):
2520 chan_type=chandev_type_lcs;
2522 case (osad_stridx*stridx_mult):
2523 chan_type=chandev_type_osad;
2525 case (qeth_stridx*stridx_mult):
2526 chan_type=chandev_type_qeth;
2533 if(ints[0]<2||ints[0]>6)
2535 chandev_add_force(chan_type,endlong,ints[1],ints[2],
2536 0,ints[3],ints[4],ints[5],ints[6],
2539 case (claw_stridx*stridx_mult)|isnum|iscomma:
2540 case (claw_stridx*stridx_mult)|iscomma:
2541 if(ints[0]>=2&&ints[0]<=5)
2543 char *host_name,*adapter_name,*api_type;
2544 char *clawstr=alloca(strlen(currstr)+1);
2546 strcpy(clawstr,currstr);
2547 if(!(chandev_get_string(&clawstr,&host_name)==2&&
2548 chandev_get_string(&clawstr,&adapter_name)==2&&
2549 chandev_get_string(&clawstr,&api_type)==1&&
2550 chandev_add_force(chandev_type_claw,
2551 endlong,ints[1],ints[2],0,
2552 ints[3],0,ints[4],ints[5],
2553 host_name,adapter_name,api_type)==0))
2560 case (del_parms_stridx*stridx_mult):
2562 case (del_parms_stridx*stridx_mult)|iscomma:
2571 chandev_remove_parms(ints[1],ints[2],ints[3]);
2573 case (del_force_stridx*stridx_mult)|iscomma:
2576 chandev_del_force(ints[1]);
2578 case (del_force_stridx*stridx_mult):
2579 chandev_del_force(-1);
2581 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
2582 case (use_devno_names_stridx*stridx_mult):
2583 chandev_use_devno_names=TRUE;
2585 case (dont_use_devno_names_stridx*stridx_mult):
2586 chandev_use_devno_names=FALSE;
2589 case (cautious_auto_detect_stridx*stridx_mult):
2590 chandev_cautious_auto_detect=TRUE;
2592 case (non_cautious_auto_detect_stridx*stridx_mult):
2593 chandev_cautious_auto_detect=FALSE;
2595 case (add_model_stridx*stridx_mult)|iscomma:
2605 ints[7]=default_msck_bits;
2611 chandev_add_model(ints[1],ints[2],ints[3],
2612 ints[4],ints[5],ints[6],ints[7],ints[8],ints[9]);
2614 case (del_model_stridx*stridx_mult)|iscomma:
2615 if(ints[0]<2||ints[0]>4)
2622 chandev_del_model(ints[1],ints[2],ints[3],ints[4]);
2624 case del_all_models_stridx*stridx_mult:
2625 chandev_remove_all_models();
2627 case reset_conf_stridx*stridx_mult:
2629 chandev_init_default_models();
2631 case reset_conf_clean_stridx*stridx_mult:
2634 case shutdown_stridx*stridx_mult:
2635 chandev_shutdown_all();
2637 case (shutdown_stridx*stridx_mult)|iscomma:
2642 chandev_shutdown_by_name(str);
2647 chandev_shutdown_by_devno(ints[1]);
2653 case reprobe_stridx*stridx_mult:
2656 case unregister_probe_stridx*stridx_mult:
2657 chandev_free_all_list((list **)&chandev_probelist_head);
2659 case (unregister_probe_stridx*stridx_mult)|iscomma:
2662 chandev_unregister_probe((chandev_probefunc)ints[1]);
2664 case (unregister_probe_by_chan_type_stridx*stridx_mult)|iscomma:
2667 chandev_unregister_probe_by_chan_type((chandev_type)ints[1]);
2669 case read_conf_stridx*stridx_mult:
2672 printk("attempt to recursively call read_conf\n");
2675 chandev_read_conf();
2677 case dont_read_conf_stridx*stridx_mult:
2678 atomic_set(&chandev_conf_read,TRUE);
2680 case (persist_stridx*stridx_mult)|iscomma:
2682 chandev_persistent=ints[1];
2695 /* eat up stuff till next string */
2696 while(*(currstr++));
2703 printk("chandev_setup %s %s",(val==0 ? "unknown verb":"bad argument"),instr);
2706 printk("%s %d interpreted as %s",errstr,lineno,interpretstr);
2710 printk(" after the last semicolon\n");
2712 printk(" before semicolon no %d",cnt);
2715 printk(".\n Type man chandev for more info.\n\n");
2719 #define CHANDEV_KEYWORD "chandev="
2720 static int chandev_setup_bootargs(char *str,int paramno)
2725 for(len=0;str[len]!=0&&!isspace(str[len]);len++);
2726 copystr=alloca(len+1);
2727 strncpy(copystr,str,len);
2729 if(chandev_setup(FALSE,copystr,"at "CHANDEV_KEYWORD" bootparam no",paramno)==0)
2736 We can't parse using a __setup function as kmalloc isn't available
2739 static void __init chandev_parse_args(void)
2741 #define CHANDEV_KEYWORD "chandev="
2742 extern char saved_command_line[];
2743 int cnt,len,paramno=1;
2745 len=strlen(saved_command_line)-sizeof(CHANDEV_KEYWORD);
2746 for(cnt=0;cnt<len;cnt++)
2748 if(strncmp(&saved_command_line[cnt],CHANDEV_KEYWORD,
2749 sizeof(CHANDEV_KEYWORD)-1)==0)
2751 cnt+=(sizeof(CHANDEV_KEYWORD)-1);
2752 cnt+=chandev_setup_bootargs(&saved_command_line[cnt],paramno);
2758 int chandev_do_setup(int in_read_conf,char *buff,int size)
2760 int curr,comment=FALSE,newline=FALSE,oldnewline=TRUE;
2761 char *startline=NULL,*endbuff=&buff[size];
2766 for(;buff<=endbuff;curr++,buff++)
2768 if(*buff==0xa||*buff==0xc||*buff==0)
2770 if(*buff==0xa||*buff==0)
2783 if(startline==NULL&&isalpha(*buff))
2785 if(startline&&(buff>startline)&&(oldnewline==FALSE)&&(newline==TRUE))
2787 if((chandev_setup(in_read_conf,startline," on line no",lineno))==0)
2799 static void chandev_read_conf(void)
2801 #define CHANDEV_FILE "/etc/chandev.conf"
2802 struct stat statbuf;
2804 int curr,left,len,fd;
2807 /* if called from chandev_register_and_probe &
2808 the driver is compiled into the kernel the
2809 parameters will need to be passed in from
2810 the kernel boot parameter line as the root
2811 fs is not mounted yet, we can't wait here.
2813 if(in_interrupt()||current->fs->root==NULL)
2815 atomic_set(&chandev_conf_read,TRUE);
2818 if(stat(CHANDEV_FILE,&statbuf)==0)
2821 buff=vmalloc(statbuf.st_size+1);
2825 if((fd=open(CHANDEV_FILE,O_RDONLY,0))!=-1)
2828 left=statbuf.st_size;
2829 while((len=read(fd,&buff[curr],left))>0)
2837 chandev_do_setup(TRUE,buff,statbuf.st_size);
2844 static void chandev_read_conf_if_necessary(void)
2846 if(in_interrupt()||current->fs->root==NULL)
2848 if(!atomic_compare_and_swap(FALSE,TRUE,&chandev_conf_read))
2849 chandev_read_conf();
2852 #ifdef CONFIG_PROC_FS
2853 #define chandev_printf(exitchan,args...) \
2854 splen=sprintf(spbuff,##args); \
2856 if(spoffset>offset) { \
2860 if(currlen>=length) \
2863 void sprintf_msck(char *buff,int auto_msck_recovery)
2865 chandev_msck_status idx;
2866 int first_time=TRUE;
2868 for(idx=chandev_status_first_msck;idx<chandev_status_last_msck;idx++)
2870 if((1<<(idx-1))&auto_msck_recovery)
2872 buff+=sprintf(buff,"%s%s",(first_time ? "":","),
2873 msck_status_strs[idx]);
2879 static int chandev_read_proc(char *page, char **start, off_t offset,
2880 int length, int *eof, void *data)
2882 char *spbuff=*start=page;
2883 int currlen=0,splen=0;
2885 chandev_model_info *curr_model;
2886 chandev_noauto_range *curr_noauto;
2887 chandev_force *curr_force;
2888 chandev_activelist *curr_device;
2889 chandev_probelist *curr_probe;
2890 chandev_msck_range *curr_msck_range;
2891 s390_dev_info_t curr_devinfo;
2892 int pass,chandevs_detected,curr_irq,loopcnt;
2893 chandev_irqinfo *read_irqinfo,*write_irqinfo,*data_irqinfo;
2897 chandev_printf(chan_exit,"\n%s\n"
2898 "*'s for cu/dev type/models indicate don't cares\n",chandev_keydescript);
2899 chandev_printf(chan_exit,"\ncautious_auto_detect: %s\n",chandev_cautious_auto_detect ? "on":"off");
2900 chandev_printf(chan_exit,"\npersist = 0x%02x\n",chandev_persistent);
2901 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
2902 chandev_printf(chan_exit,"\nuse_devno_names: %s\n\n",chandev_use_devno_names ? "on":"off");
2905 if(chandev_models_head)
2907 chandev_printf(chan_exit,"Channels enabled for detection\n");
2908 chandev_printf(chan_exit," chan cu cu dev dev max checksum use hw auto recovery\n");
2909 chandev_printf(chan_exit," type type model type model port_no. received stats type\n");
2910 chandev_printf(chan_exit,"==============================================================================\n");
2911 for_each(curr_model,chandev_models_head)
2915 chandev_sprint_devinfo(buff[0],curr_model->cu_type,
2916 curr_model->cu_model,
2917 curr_model->dev_type,
2918 curr_model->dev_model);
2919 sprintf_msck(buff[1],curr_model->auto_msck_recovery);
2920 chandev_printf(chan_exit," 0x%02x %s%3d %s %s %s\n",
2921 curr_model->chan_type,buff[0],
2922 (int)curr_model->max_port_no,
2923 curr_model->default_checksum_received_ip_pkts ? "yes":"no ",
2924 curr_model->default_use_hw_stats ? "yes":"no ",
2929 if(chandev_noauto_head)
2931 chandev_printf(chan_exit,"\nNo auto devno ranges\n");
2932 chandev_printf(chan_exit," From To \n");
2933 chandev_printf(chan_exit,"====================\n");
2934 for_each(curr_noauto,chandev_noauto_head)
2936 chandev_printf(chan_exit," 0x%04x 0x%04x\n",
2937 curr_noauto->lo_devno,
2938 curr_noauto->hi_devno);
2941 if(chandev_msck_range_head)
2944 chandev_printf(chan_exit,"\nAutomatic machine check recovery devno ranges\n");
2945 chandev_printf(chan_exit," From To automatic recovery type\n");
2946 chandev_printf(chan_exit,"===========================================\n");
2947 for_each(curr_msck_range,chandev_msck_range_head)
2949 sprintf_msck(buff[0],curr_msck_range->auto_msck_recovery);
2950 chandev_printf(chan_exit," 0x%04x 0x%04x %s\n",
2951 curr_msck_range->lo_devno,
2952 curr_msck_range->hi_devno,buff[0])
2955 if(chandev_force_head)
2957 chandev_printf(chan_exit,"\nForced devices\n");
2958 chandev_printf(chan_exit," chan defif read write data memory port ip hw host adapter api\n");
2959 chandev_printf(chan_exit," type num devno devno devno usage(k) protocol no. chksum stats name name name\n");
2960 chandev_printf(chan_exit,"===============================================================================================\n");
2961 for_each(curr_force,chandev_force_head)
2963 if(curr_force->memory_usage_in_k==0)
2964 strcpy(buff[0],"default");
2966 sprintf(buff[0],"%6d",curr_force->memory_usage_in_k);
2967 chandev_printf(chan_exit," 0x%02x %3d 0x%04x 0x%04x 0x%04x %7s %3d %1d %1d%s",
2968 (int)curr_force->chan_type,(int)curr_force->devif_num,
2969 (int)curr_force->read_lo_devno,(int)curr_force->write_hi_devno,
2970 (int)curr_force->data_devno,buff[0],
2971 (int)curr_force->port_protocol_no,(int)curr_force->checksum_received_ip_pkts,
2972 (int)curr_force->use_hw_stats,curr_force->chan_type==chandev_type_claw ? "":"\n");
2973 if(curr_force->chan_type==chandev_type_claw)
2975 chandev_printf(chan_exit," %9s %9s %9s\n",
2976 curr_force->claw.host_name,
2977 curr_force->claw.adapter_name,
2978 curr_force->claw.api_type);
2983 if(chandev_probelist_head)
2985 #if CONFIG_ARCH_S390X
2986 chandev_printf(chan_exit,"\nRegistered probe functions\n"
2987 "probefunc shutdownfunc msck_notfunc chan devices devices\n"
2988 " type found active\n"
2989 "==================================================================================\n");
2991 chandev_printf(chan_exit,"\nRegistered probe functions\n"
2992 "probefunc shutdownfunc msck_notfunc chan devices devices\n"
2993 " type found active\n"
2994 "===============================================================\n");
2996 for_each(curr_probe,chandev_probelist_head)
2998 int devices_active=0;
2999 for_each(curr_device,chandev_activelist_head)
3001 if(curr_device->probefunc==curr_probe->probefunc)
3004 chandev_printf(chan_exit,"0x%p 0x%p 0x%p 0x%02x %d %d\n",
3005 curr_probe->probefunc,
3006 curr_probe->shutdownfunc,
3007 curr_probe->msck_notfunc,
3008 curr_probe->chan_type,
3009 curr_probe->devices_found,
3013 if(chandev_activelist_head)
3015 unsigned long long total_memory_usage_in_k=0;
3016 chandev_printf(chan_exit,
3017 "\nInitialised Devices\n"
3018 " read write data read write data chan port dev dev memory read msck write msck data msck\n"
3019 " irq irq irq devno devno devno type no. ptr name usage(k) status status status\n"
3020 "=====================================================================================================================\n");
3021 /* We print this list backwards for cosmetic reasons */
3022 for(curr_device=chandev_activelist_head;
3023 curr_device->next!=NULL;curr_device=curr_device->next);
3026 read_irqinfo=curr_device->read_irqinfo;
3027 write_irqinfo=curr_device->write_irqinfo;
3028 data_irqinfo=curr_device->data_irqinfo;
3031 sprintf(buff[0],"0x%04x",data_irqinfo->sch.irq);
3032 sprintf(buff[1],"0x%04x",(int)data_irqinfo->sch.devno);
3036 strcpy(buff[0]," n/a ");
3037 strcpy(buff[1]," n/a ");
3039 if(curr_device->memory_usage_in_k<0)
3041 sprintf(buff[2],"%d",(int)-curr_device->memory_usage_in_k);
3042 total_memory_usage_in_k-=curr_device->memory_usage_in_k;
3045 strcpy(buff[2]," n/a ");
3046 chandev_printf(chan_exit,
3047 "0x%04x 0x%04x %s 0x%04x 0x%04x %s 0x%02x %2d 0x%p %-10s %6s %-12s %-12s %-12s\n",
3048 read_irqinfo->sch.irq,
3049 write_irqinfo->sch.irq,
3051 (int)read_irqinfo->sch.devno,
3052 (int)write_irqinfo->sch.devno,
3054 curr_device->chan_type,(int)curr_device->port_no,
3055 curr_device->dev_ptr,curr_device->devname,
3057 msck_status_strs[read_irqinfo->msck_status],
3058 msck_status_strs[write_irqinfo->msck_status],
3059 data_irqinfo ? msck_status_strs[data_irqinfo->msck_status] :
3061 get_prev((list *)chandev_activelist_head,
3062 (list *)curr_device,
3063 (list **)&curr_device);
3065 chandev_printf(chan_exit,"\nTotal device memory usage %Luk.\n",total_memory_usage_in_k);
3067 chandevs_detected=FALSE;
3068 for(pass=FALSE;pass<=TRUE;pass++)
3070 if(pass&&chandevs_detected)
3072 chandev_printf(chan_exit,"\nchannels detected\n");
3073 chandev_printf(chan_exit," chan cu cu dev dev in chandev\n");
3074 chandev_printf(chan_exit," irq devno type type model type model pim chpids use reg.\n");
3075 chandev_printf(chan_exit,"===============================================================================\n");
3077 for(curr_irq=get_irq_first(),loopcnt=0;curr_irq>=0; curr_irq=get_irq_next(curr_irq),loopcnt++)
3081 printk(KERN_ERR"chandev_read_proc detected infinite loop bug in get_irq_next\n");
3084 if(chandev_is_chandev(curr_irq,&curr_devinfo,&curr_force,&curr_model))
3086 schib_t *curr_schib;
3087 curr_schib=s390_get_schib(curr_irq);
3088 chandevs_detected=TRUE;
3091 chandev_printf(chan_exit,"0x%04x 0x%04x 0x%02x 0x%04x 0x%02x 0x%04x 0x%02x 0x%02x 0x%016Lx %-5s%-5s\n",
3092 curr_irq,curr_devinfo.devno,
3093 ( curr_force ? curr_force->chan_type :
3094 ( curr_model ? curr_model->chan_type :
3095 chandev_type_none )),
3096 (int)curr_devinfo.sid_data.cu_type,
3097 (int)curr_devinfo.sid_data.cu_model,
3098 (int)curr_devinfo.sid_data.dev_type,
3099 (int)curr_devinfo.sid_data.dev_model,
3100 (int)(curr_schib ? curr_schib->pmcw.pim : 0),
3101 *(long long *)(curr_schib ? &curr_schib->pmcw.chpid[0] : 0),
3102 (curr_devinfo.status&DEVSTAT_DEVICE_OWNED) ? "yes":"no ",
3103 (chandev_get_irqinfo_by_irq(curr_irq) ? "yes":"no "));
3112 if(chandev_parms_head)
3114 chandev_parms *curr_parms;
3116 chandev_printf(chan_exit,"\n driver specific parameters\n");
3117 chandev_printf(chan_exit,"chan lo hi driver\n");
3118 chandev_printf(chan_exit,"type devno devno parameters\n");
3119 chandev_printf(chan_exit,"=============================================================================\n");
3120 for_each(curr_parms,chandev_parms_head)
3122 chandev_printf(chan_exit,"0x%02x 0x%04x 0x%04x %s\n",
3123 curr_parms->chan_type,(int)curr_parms->lo_devno,
3124 (int)curr_parms->hi_devno,curr_parms->parmstr);
3130 if(currlen>length) {
3131 /* rewind to previous printf so that we are correctly
3132 * aligned if we get called to print another page.
3141 static int chandev_write_proc(struct file *file, const char *buffer,
3142 unsigned long count, void *data)
3150 buff=vmalloc(count+1);
3153 rc = copy_from_user(buff,buffer,count);
3155 goto chandev_write_exit;
3156 chandev_do_setup(FALSE,buff,count);
3167 static void __init chandev_create_proc(void)
3169 struct proc_dir_entry *dir_entry=
3170 create_proc_entry("chandev",0644,
3174 dir_entry->read_proc=&chandev_read_proc;
3175 dir_entry->write_proc=&chandev_write_proc;
3181 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
3184 int __init chandev_init(void)
3186 atomic_set(&chandev_initialised,TRUE);
3187 chandev_parse_args();
3188 chandev_init_default_models();
3190 chandev_create_proc();
3192 chandev_msck_task_tq.routine=
3194 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
3195 INIT_LIST_HEAD(&chandev_msck_task_tq.list);
3196 chandev_msck_task_tq.sync=0;
3198 chandev_msck_task_tq.data=NULL;
3199 chandev_last_startmsck_list_update=chandev_last_machine_check=jiffies-HZ;
3200 atomic_set(&chandev_msck_thread_lock,1);
3201 chandev_lock_owner=CHANDEV_INVALID_LOCK_OWNER;
3203 spin_lock_init(&chandev_spinlock);
3204 spin_lock_init(&chandev_not_oper_spinlock);
3205 atomic_set(&chandev_new_msck,FALSE);
3208 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
3209 __initcall(chandev_init);
3212 int chandev_register_and_probe(chandev_probefunc probefunc,
3213 chandev_shutdownfunc shutdownfunc,
3214 chandev_msck_notification_func msck_notfunc,
3215 chandev_type chan_type)
3217 chandev_probelist *new_probe,*curr_probe;
3218 /* Avoid chicked & egg situations where we may be called before we */
3219 /* are initialised. */
3221 chandev_interrupt_check();
3222 if(!atomic_compare_and_swap(FALSE,TRUE,&chandev_initialised))
3225 for_each(curr_probe,chandev_probelist_head)
3227 if(curr_probe->probefunc==probefunc)
3230 printk("chandev_register_and_probe detected duplicate probefunc %p"
3231 " for chan_type 0x%02x \n",probefunc,chan_type);
3236 if((new_probe=chandev_alloc(sizeof(chandev_probelist))))
3238 new_probe->probefunc=probefunc;
3239 new_probe->shutdownfunc=shutdownfunc;
3240 new_probe->msck_notfunc=msck_notfunc;
3241 new_probe->chan_type=chan_type;
3242 new_probe->devices_found=0;
3243 chandev_add_to_list((list **)&chandev_probelist_head,new_probe);
3246 return(new_probe ? new_probe->devices_found:-ENOMEM);
3249 void chandev_unregister(chandev_probefunc probefunc,int call_shutdown)
3251 chandev_probelist *curr_probe;
3252 chandev_activelist *curr_device,*next_device;
3254 chandev_interrupt_check();
3256 for_each(curr_probe,chandev_probelist_head)
3258 if(curr_probe->probefunc==probefunc)
3260 for_each_allow_delete(curr_device,next_device,chandev_activelist_head)
3261 if(curr_device->probefunc==probefunc&&call_shutdown)
3262 chandev_shutdown(curr_device);
3263 chandev_free_listmember((list **)&chandev_probelist_head,
3264 (list *)curr_probe);
3272 int chandev_persist(chandev_type chan_type)
3274 return((chandev_persistent&chan_type) ? TRUE:FALSE);
3277 EXPORT_SYMBOL(chandev_register_and_probe);
3278 EXPORT_SYMBOL(chandev_request_irq);
3279 EXPORT_SYMBOL(chandev_unregister);
3280 EXPORT_SYMBOL(chandev_initdevice);
3281 EXPORT_SYMBOL(chandev_build_device_name);
3282 EXPORT_SYMBOL(chandev_initnetdevice);
3283 EXPORT_SYMBOL(chandev_init_netdev);
3284 EXPORT_SYMBOL(chandev_use_devno_names);
3285 EXPORT_SYMBOL(chandev_free_irq);
3286 EXPORT_SYMBOL(chandev_add_model);
3287 EXPORT_SYMBOL(chandev_del_model);
3288 EXPORT_SYMBOL(chandev_persist);