tape.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:34k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /***********************************************************************
  2.  *  drivers/s390/char/tape.c
  3.  *    tape device driver for S/390 and zSeries tapes.
  4.  *
  5.  *  S390 and zSeries version
  6.  *    Copyright (C) 2001 IBM Corporation
  7.  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  8.  *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
  9.  *
  10.  ***********************************************************************
  11.  */
  12. #include "tapedefs.h"
  13. #include <linux/config.h>
  14. #include <linux/stddef.h>
  15. #include <linux/kernel.h>
  16. #include <linux/version.h>
  17. #include <linux/proc_fs.h>
  18. #include <linux/init.h>
  19. #include <asm/types.h>
  20. #include <asm/ccwcache.h>
  21. #include <asm/idals.h>
  22. #include <asm/ebcdic.h>
  23. #include <linux/compatmac.h>
  24. #ifdef MODULE
  25. #include <linux/module.h>
  26. #endif   
  27. #include <asm/debug.h>
  28. #ifdef CONFIG_S390_TAPE_DYNAMIC
  29. #include <asm/s390dyn.h>
  30. #endif
  31. #include "tape.h"
  32. #ifdef CONFIG_S390_TAPE_3490
  33. #include "tape3490.h"
  34. #endif
  35. #ifdef CONFIG_S390_TAPE_3480
  36. #include "tape3480.h"
  37. #endif
  38. #ifdef CONFIG_S390_TAPE_BLOCK
  39. #include "tapeblock.h"
  40. #endif
  41. #ifdef CONFIG_S390_TAPE_CHAR
  42. #include "tapechar.h"
  43. #endif
  44. #ifdef CONFIG_PROC_FS
  45. #include <linux/vmalloc.h>
  46. #endif
  47. #define PRINTK_HEADER "T390:"
  48. /* state handling routines */
  49. inline void tapestate_set (tape_info_t * ti, int newstate);
  50. inline int tapestate_get (tape_info_t * ti);
  51. void tapestate_event (tape_info_t * ti, int event);
  52. /* our globals */
  53. tape_info_t *first_tape_info = NULL;
  54. tape_discipline_t *first_discipline = NULL;
  55. tape_frontend_t *first_frontend = NULL;
  56. devreg_t* tape_devreg[128];
  57. int devregct=0;
  58. #ifdef TAPE_DEBUG
  59. debug_info_t *tape_debug_area = NULL;
  60. #endif
  61. char* state_verbose[TS_SIZE]={
  62.     "TS_UNUSED",  "TS_IDLE", "TS_DONE", "TS_FAILED",
  63.     "TS_BLOCK_INIT",
  64.     "TS_BSB_INIT",
  65.     "TS_BSF_INIT",
  66.     "TS_DSE_INIT",
  67.     "TS_EGA_INIT",
  68.     "TS_FSB_INIT",
  69.     "TS_FSF_INIT",
  70.     "TS_LDI_INIT",
  71.     "TS_LBL_INIT",
  72.     "TS_MSE_INIT",
  73.     "TS_NOP_INIT",
  74.     "TS_RBA_INIT",
  75.     "TS_RBI_INIT",
  76.     "TS_RBU_INIT",
  77.     "TS_RBL_INIT",
  78.     "TS_RDC_INIT",
  79.     "TS_RFO_INIT",
  80.     "TS_RSD_INIT",
  81.     "TS_REW_INIT",
  82.     "TS_REW_RELEASE_INIT",
  83.     "TS_RUN_INIT",
  84.     "TS_SEN_INIT",
  85.     "TS_SID_INIT",
  86.     "TS_SNP_INIT",
  87.     "TS_SPG_INIT",
  88.     "TS_SWI_INIT",
  89.     "TS_SMR_INIT",
  90.     "TS_SYN_INIT",
  91.     "TS_TIO_INIT",
  92.     "TS_UNA_INIT",
  93.     "TS_WRI_INIT",
  94.     "TS_WTM_INIT",
  95.     "TS_NOT_OPER"};
  96. char* event_verbose[TE_SIZE]= {
  97.     "TE_START", "TE_DONE", "TE_FAILED", "TE_ERROR", "TE_OTHER"};
  98. /* our root devfs handle */
  99. #ifdef CONFIG_DEVFS_FS
  100. devfs_handle_t tape_devfs_root_entry;
  101. inline void
  102. tape_mkdevfsroots (tape_info_t* ti) 
  103. {
  104.     char devno [5];
  105.     sprintf (devno,"%04x",ti->devinfo.devno);
  106.     ti->devfs_dir=devfs_mk_dir (tape_devfs_root_entry, devno, ti);
  107. }
  108. inline void
  109. tape_rmdevfsroots (tape_info_t* ti)
  110. {
  111.     devfs_unregister (ti->devfs_dir);
  112. }
  113. #endif
  114. #ifdef CONFIG_PROC_FS
  115. /* our proc tapedevices entry */
  116. static struct proc_dir_entry *tape_devices_entry;
  117. typedef struct {
  118. char *data;
  119. int len;
  120. } tempinfo_t;
  121. static int
  122. tape_devices_open (struct inode *inode, struct file *file)
  123. {
  124.     int size=80;
  125.     tape_info_t* ti;
  126.     tempinfo_t* tempinfo;
  127.     char* data;
  128.     int pos=0;
  129.     tempinfo = kmalloc (sizeof(tempinfo_t),GFP_KERNEL);
  130.     if (!tempinfo)
  131.         return -ENOMEM;
  132.     for (ti=first_tape_info;ti!=NULL;ti=ti->next)
  133.         size+=80; // FIXME: Guess better!
  134.     data=vmalloc(size);
  135.     if (!data) {
  136.         kfree (tempinfo);
  137.         return -ENOMEM;
  138.     }
  139.     pos+=sprintf(data+pos,"TapeNotDevNotCuTypetCuModeltDevTypetDevModeltStaten");
  140.     for (ti=first_tape_info;ti!=NULL;ti=ti->next) {
  141.         pos+=sprintf(data+pos,"%dt%04Xt%04Xt%02Xt%04Xt%02Xtt%sn",ti->rew_minor/2,
  142.                      ti->devinfo.devno,ti->devinfo.sid_data.cu_type,
  143.                      ti->devinfo.sid_data.cu_model,ti->devinfo.sid_data.dev_type,
  144.                      ti->devinfo.sid_data.dev_model,((tapestate_get(ti) >= 0) &&
  145.                                                        (tapestate_get(ti) < TS_SIZE)) ?
  146.                      state_verbose[tapestate_get (ti)] : "TS UNKNOWN");
  147.     }
  148.     tempinfo->len=pos;
  149.     tempinfo->data=data;
  150.     file->private_data= (void*) tempinfo;
  151. #ifdef MODULE
  152.     MOD_INC_USE_COUNT;
  153. #endif
  154.     return 0;
  155. }
  156. static ssize_t
  157. tape_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * offset)
  158. {
  159. loff_t len;
  160. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  161. if (*offset >= p_info->len) {
  162. return 0; /* EOF */
  163. } else {
  164. len =  user_len<(p_info->len - *offset)?user_len:(p_info->len - *offset);
  165. if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
  166. return -EFAULT;
  167. (*offset) += len;
  168. return len; /* number of bytes "read" */
  169. }
  170. }
  171. static int
  172. tape_devices_release (struct inode *inode, struct file *file)
  173. {
  174. int rc = 0;
  175. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  176. if (p_info) {
  177. if (p_info->data)
  178. vfree (p_info->data);
  179. kfree (p_info);
  180. }
  181. #ifdef MODULE
  182.         MOD_DEC_USE_COUNT;
  183. #endif
  184. return rc;
  185. }
  186. static struct file_operations tape_devices_file_ops =
  187. {
  188. read:tape_devices_read, /* read */
  189. open:tape_devices_open, /* open */
  190. release:tape_devices_release, /* close */
  191. };
  192. static struct inode_operations tape_devices_inode_ops =
  193. {
  194. #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
  195. default_file_ops:&tape_devices_file_ops /* file ops */
  196. #endif /* LINUX_IS_24 */
  197. };
  198. #endif /* CONFIG_PROC_FS */
  199. /* SECTION: Parameters for tape */
  200. char *tape[256] = { NULL, };
  201. #ifndef MODULE
  202. static char tape_parm_string[1024] __initdata = { 0, };
  203. static void
  204. tape_split_parm_string (char *str)
  205. {
  206. char *tmp = str;
  207. int count = 0;
  208. while (tmp != NULL && *tmp != '') {
  209. char *end;
  210. int len;
  211. end = strchr (tmp, ',');
  212. if (end == NULL) {
  213. len = strlen (tmp) + 1;
  214. } else {
  215. len = (long) end - (long) tmp + 1;
  216. *end = '';
  217. end++;
  218. }
  219. tape[count] = kmalloc (len * sizeof (char), GFP_ATOMIC);
  220. if (tape[count] == NULL) {
  221. printk (KERN_WARNING PRINTK_HEADER
  222. "can't store tape= parameter no %dn",
  223. count + 1);
  224. break;
  225. }
  226. memset (tape[count], 0, len * sizeof (char));
  227. memcpy (tape[count], tmp, len * sizeof (char));
  228. count++;
  229. tmp = end;
  230. };
  231. }
  232. void __init
  233. tape_parm_setup (char *str, int *ints)
  234. {
  235. int len = strlen (tape_parm_string);
  236. if (len != 0) {
  237. strcat (tape_parm_string, ",");
  238. }
  239. strcat (tape_parm_string, str);
  240. }
  241. int __init
  242. tape_parm_call_setup (char *str)
  243. {
  244. int dummy;
  245. tape_parm_setup (str, &dummy);
  246. return 1;
  247. }
  248. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,2,16))
  249. __setup("tape=", tape_parm_call_setup);
  250. #endif   /* kernel <2.2.19 */
  251. #endif   /* not defined MODULE */
  252. static inline int
  253. tape_parm_strtoul (char *str, char **stra)
  254. {
  255. char *temp = str;
  256. int val;
  257. if (*temp == '0') {
  258. temp++; /* strip leading zero */
  259. if (*temp == 'x')
  260. temp++; /* strip leading x */
  261. }
  262. val = simple_strtoul (temp, &temp, 16); /* interpret anything as hex */
  263. *stra = temp;
  264. return val;
  265. }
  266. static inline devreg_t *
  267. tape_create_devreg (int devno)
  268. {
  269. devreg_t *devreg = kmalloc (sizeof (devreg_t), GFP_KERNEL);
  270. if (devreg != NULL) {
  271. memset (devreg, 0, sizeof (devreg_t));
  272. devreg->ci.devno = devno;
  273. devreg->flag = DEVREG_TYPE_DEVNO;
  274. devreg->oper_func = tape_oper_handler;
  275. }
  276. return devreg;
  277. }
  278. static inline void
  279. tape_parm_parse (char **str)
  280. {
  281. char *temp;
  282. int from, to,i,irq=0,rc,retries=0,tape_num=0;
  283.         s390_dev_info_t dinfo;
  284.         tape_info_t* ti,*tempti;
  285.         tape_discipline_t* disc;
  286.         long lockflags;
  287. if (*str==NULL) {
  288.             /* no params present -> leave */
  289.             return;
  290. }
  291. while (*str) {
  292. temp = *str;
  293. from = 0;
  294. to = 0;
  295.                 /* turn off autodetect mode, if any range is present */
  296.                 from = tape_parm_strtoul (temp, &temp);
  297.                 to = from;
  298.                 if (*temp == '-') {
  299.                     temp++;
  300.                     to = tape_parm_strtoul (temp, &temp);
  301.                 }
  302.                 for (i=from;i<=to;i++) {
  303.                     retries=0;
  304.                     // register for attch/detach of a devno
  305.                     tape_devreg[devregct]=tape_create_devreg(i);
  306.                     if (tape_devreg[devregct]==NULL) {
  307.                         PRINT_WARN ("Could not create devreg for devno %04x, dyn. attach for this devno deactivated.n",i);
  308.                     } else {
  309.                         s390_device_register (tape_devreg[devregct++]);
  310.                     }
  311.                     // we are activating a device if it is present
  312.                     for (irq = get_irq_first(); irq!=-ENODEV; irq=get_irq_next(irq)) {
  313.                         rc = get_dev_info_by_irq (irq, &dinfo);
  314.                      
  315.                         disc = first_discipline;
  316.                         while ((dinfo.devno == i) && (disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))
  317.                             disc = (tape_discipline_t *) (disc->next);
  318.                         if ((disc == NULL) || (rc == -ENODEV) || (i!=dinfo.devno)) {
  319.                             continue;
  320.                         }
  321. #ifdef TAPE_DEBUG
  322.                         debug_text_event (tape_debug_area,3,"det irq:  ");
  323.                         debug_int_event (tape_debug_area,3,irq);
  324.                         debug_text_event (tape_debug_area,3,"cu:       ");
  325.                         debug_int_event (tape_debug_area,3,disc->cu_type);
  326. #endif /* TAPE_DEBUG */
  327.                         PRINT_INFO ("using devno %04x with discipline %04x on irq %d as tape device %dn",dinfo.devno,dinfo.sid_data.cu_type,irq,tape_num/2);
  328.                         /* Allocate tape structure  */
  329.                         ti = kmalloc (sizeof (tape_info_t), GFP_ATOMIC);
  330.                         if (ti == NULL) {
  331. #ifdef TAPE_DEBUG
  332.                             debug_text_exception (tape_debug_area,3,"ti:no mem ");
  333. #endif /* TAPE_DEBUG */
  334.                             PRINT_INFO ("tape: can't allocate memory for "
  335.                                         "tape info structuren");
  336.                             continue;
  337.                         }
  338.                         memset(ti,0,sizeof(tape_info_t));
  339.                         ti->discipline = disc;
  340.                         disc->tape = ti;
  341.                         rc = tape_setup (ti, irq, tape_num);
  342.                         if (rc) {
  343. #ifdef TAPE_DEBUG
  344.                             debug_text_event (tape_debug_area,3,"tsetup err");
  345.                             debug_int_exception (tape_debug_area,3,rc);
  346. #endif /* TAPE_DEBUG */
  347.                             kfree (ti);
  348.                         } else {
  349.                             s390irq_spin_lock_irqsave (irq, lockflags);
  350.                             if (first_tape_info == NULL) {
  351.                                 first_tape_info = ti;
  352.                             } else {
  353.                                 tempti = first_tape_info;
  354.                                 while (tempti->next != NULL)
  355.                                     tempti = tempti->next;
  356.                                 tempti->next = ti;
  357.                             }
  358.                             s390irq_spin_unlock_irqrestore (irq, lockflags);
  359.                         }
  360.                     }
  361.                     tape_num+=2;
  362.                 }
  363.                 str++;
  364.         }
  365. }
  366. /* SECTION: Managing wrappers for ccwcache */
  367. #define TAPE_EMERGENCY_REQUESTS 16
  368. static ccw_req_t *tape_emergency_req[TAPE_EMERGENCY_REQUESTS] =
  369. {NULL,};
  370. static spinlock_t tape_emergency_req_lock = SPIN_LOCK_UNLOCKED;
  371. static void
  372. tape_init_emergency_req (void)
  373. {
  374. int i;
  375. for (i = 0; i < TAPE_EMERGENCY_REQUESTS; i++) {
  376. tape_emergency_req[i] = (ccw_req_t *) get_free_page (GFP_KERNEL);
  377. }
  378. }
  379. #ifdef MODULE // We only cleanup the emergency requests on module unload.
  380. static void
  381. tape_cleanup_emergency_req (void)
  382. {
  383. int i;
  384. for (i = 0; i < TAPE_EMERGENCY_REQUESTS; i++) {
  385. if (tape_emergency_req[i])
  386. free_page ((long) (tape_emergency_req[i]));
  387. else
  388. printk (KERN_WARNING PRINTK_HEADER "losing one page for 'in-use' emergency requestn");
  389. }
  390. }
  391. #endif
  392. ccw_req_t *
  393. tape_alloc_request (char *magic, int cplength, int datasize)
  394. {
  395. ccw_req_t *rv = NULL;
  396. int i;
  397. if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) {
  398. return rv;
  399. }
  400. if (cplength * sizeof (ccw1_t) + datasize + sizeof (ccw_req_t) > PAGE_SIZE) {
  401. return NULL;
  402. }
  403. spin_lock (&tape_emergency_req_lock);
  404. for (i = 0; i < TAPE_EMERGENCY_REQUESTS; i++) {
  405. if (tape_emergency_req[i] != NULL) {
  406. rv = tape_emergency_req[i];
  407. tape_emergency_req[i] = NULL;
  408. }
  409. }
  410. spin_unlock (&tape_emergency_req_lock);
  411. if (rv) {
  412. memset (rv, 0, PAGE_SIZE);
  413. rv->cache = (kmem_cache_t *) (tape_emergency_req + i);
  414. strncpy ((char *) (&rv->magic), magic, 4);
  415. ASCEBC ((char *) (&rv->magic), 4);
  416. rv->cplength = cplength;
  417. rv->datasize = datasize;
  418. rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
  419. rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
  420. }
  421. return rv;
  422. }
  423. void
  424. tape_free_request (ccw_req_t * request)
  425. {
  426. if (request->cache >= (kmem_cache_t *) tape_emergency_req &&
  427.     request->cache <= (kmem_cache_t *) (tape_emergency_req + TAPE_EMERGENCY_REQUESTS)) {
  428. *((ccw_req_t **) (request->cache)) = request;
  429. } else {
  430. clear_normalized_cda ((ccw1_t *) (request->cpaddr)); // avoid memory leak caused by modeset_byte
  431. ccw_free_request (request);
  432. }
  433. }
  434. /*
  435.  * Allocate a ccw request and reserve it for tape driver
  436.  */
  437. inline
  438.  ccw_req_t *
  439. tape_alloc_ccw_req (tape_info_t * ti, int cplength, int datasize)
  440. {
  441. char tape_magic_id[] = "tape";
  442. ccw_req_t *cqr = NULL;
  443. if (!ti)
  444. return NULL;
  445. cqr = tape_alloc_request (tape_magic_id, cplength, datasize);
  446. if (!cqr) {
  447. #ifdef TAPE_DEBUG
  448. PRINT_WARN ("empty CQR generatedn");
  449. #endif
  450. }
  451. cqr->magic = TAPE_MAGIC; /* sets an identifier for tape driver   */
  452. cqr->device = ti; /* save pointer to tape info    */
  453. return cqr;
  454. }
  455. /*
  456.  * Find the tape_info_t structure associated with irq
  457.  */
  458. static inline tape_info_t *
  459. tapedev_find_info (int irq)
  460. {
  461. tape_info_t *ti;
  462. ti = first_tape_info;
  463. if (ti != NULL)
  464. do {
  465. if (ti->devinfo.irq == irq)
  466. break;
  467. } while ((ti = (tape_info_t *) ti->next) != NULL);
  468. return ti;
  469. }
  470. #define QUEUE_THRESHOLD 5
  471. /*
  472.  * Tape interrupt routine, called from Ingo's I/O layer
  473.  */
  474. void
  475. tape_irq (int irq, void *int_parm, struct pt_regs *regs)
  476. {
  477. tape_info_t *ti = tapedev_find_info (irq);
  478. /* analyse devstat and fire event */
  479. if (ti->devstat.dstat & DEV_STAT_UNIT_CHECK) {
  480. tapestate_event (ti, TE_ERROR);
  481. } else if (ti->devstat.dstat & (DEV_STAT_DEV_END)) {
  482. tapestate_event (ti, TE_DONE);
  483. } else
  484. tapestate_event (ti, TE_OTHER);
  485. }
  486. int 
  487. tape_oper_handler ( int irq, struct _devreg *dreg) {
  488.     tape_info_t* ti=first_tape_info;
  489.     tape_info_t* newtape;
  490.     int rc,tape_num,retries=0,i;
  491.     s390_dev_info_t dinfo;
  492.     tape_discipline_t* disc;
  493. #ifdef CONFIG_DEVFS_FS
  494.     tape_frontend_t* frontend;
  495. #endif
  496.     long lockflags;
  497.     while ((ti!=NULL) && (ti->devinfo.irq!=irq)) 
  498.         ti=ti->next;
  499.     if (ti!=NULL) {
  500.         // irq is (still) used by tape. tell ingo to try again later
  501.         PRINT_WARN ("Oper handler for irq %d called while irq still (internaly?) used.n",irq);
  502.         return -EAGAIN;
  503.     }
  504.     // irq is not used by tape
  505.     rc = get_dev_info_by_irq (irq, &dinfo);
  506.     if (rc == -ENODEV) {
  507.         retries++;
  508.         rc = get_dev_info_by_irq (irq, &dinfo);
  509.         if (retries > 5) {
  510.             PRINT_WARN ("No device information for new dev. could be retrieved.n");
  511.             return -ENODEV;
  512.         }
  513.     }
  514.     disc = first_discipline;
  515.     while ((disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))
  516.         disc = (tape_discipline_t *) (disc->next);
  517.     if (disc == NULL)
  518.         PRINT_WARN ("No matching discipline for cu_type %x found, ignoring device %04x.n",dinfo.sid_data.cu_type,dinfo.devno);
  519.     if (rc == -ENODEV) 
  520.         PRINT_WARN ("No device information for new dev. could be retrieved.n");
  521.     if ((disc == NULL) || (rc == -ENODEV))
  522.         return -ENODEV;
  523.     
  524.     /* Allocate tape structure  */
  525.     ti = kmalloc (sizeof (tape_info_t), GFP_ATOMIC);
  526.     if (ti == NULL) {
  527.         PRINT_INFO ( "tape: can't allocate memory for "
  528.                     "tape info structuren");
  529.         return -ENOBUFS;
  530.     }
  531.     memset(ti,0,sizeof(tape_info_t));
  532.     ti->discipline = disc;
  533.     disc->tape = ti;
  534.     tape_num=0;
  535.     if (*tape) {
  536.         // we have static device ranges, so fingure out the tape_num of the attached tape
  537.         for (i=0;i<devregct;i++)
  538.             if (tape_devreg[i]->ci.devno==dinfo.devno) {
  539.                 tape_num=2*i;
  540.                 break;
  541.             }
  542.     } else {
  543.         // we are running in autoprobe mode, find a free tape_num
  544.         newtape=first_tape_info;
  545.         while (newtape!=NULL) {
  546.             if (newtape->rew_minor==tape_num) {
  547.                 // tape num in use. try next one
  548.                 tape_num+=2;
  549.                 newtape=first_tape_info;
  550.             } else {
  551.                 // tape num not used by newtape. look at next tape info
  552.                 newtape=newtape->next;
  553.             }
  554.         }
  555.     }
  556.     rc = tape_setup (ti, irq, tape_num);
  557.     if (rc) {
  558.         kfree (ti);
  559.         return -ENOBUFS;
  560.     }
  561. #ifdef CONFIG_DEVFS_FS
  562.     for (frontend=first_frontend;frontend!=NULL;frontend=frontend->next) 
  563.         frontend->mkdevfstree(ti);
  564. #endif
  565.     s390irq_spin_lock_irqsave (irq,lockflags);
  566.     if (first_tape_info == NULL) {
  567.         first_tape_info = ti;
  568.     } else {
  569.         newtape = first_tape_info;
  570.         while (newtape->next != NULL)
  571.             newtape = newtape->next;
  572.         newtape->next = ti;
  573.     }
  574.     s390irq_spin_unlock_irqrestore (irq, lockflags);
  575.     return 0;
  576. }
  577. static void
  578. tape_noper_handler ( int irq, int status ) {
  579.     tape_info_t *ti=first_tape_info;
  580.     tape_info_t *lastti;
  581. #ifdef CONFIG_DEVFS_FS
  582.     tape_frontend_t *frontend;
  583. #endif
  584.     long lockflags;
  585.     s390irq_spin_lock_irqsave(irq,lockflags);
  586.     while (ti!=NULL && ti->devinfo.irq!=irq) ti=ti->next;
  587.     if (ti==NULL) return;
  588.     if (tapestate_get(ti)!=TS_UNUSED) {
  589.         // device is in use!
  590.         PRINT_WARN ("Tape #%d was detached while it was busy. Expect errors!",ti->blk_minor/2);
  591.         tapestate_set(ti,TS_NOT_OPER);
  592.         ti->rc=-ENODEV; 
  593. ti->wanna_wakeup=1;
  594. switch (tapestate_get(ti)) {
  595. case TS_REW_RELEASE_INIT:
  596.     tapestate_set(ti,TS_NOT_OPER);
  597.     wake_up (&ti->wq);
  598.     break;
  599. #ifdef CONFIG_S390_TAPE_BLOCK
  600. case TS_BLOCK_INIT:
  601.     tapestate_set(ti,TS_NOT_OPER);
  602.     schedule_tapeblock_exec_IO(ti);
  603.     break;
  604. #endif
  605. default:
  606.     tapestate_set(ti,TS_NOT_OPER);
  607.     wake_up_interruptible (&ti->wq);
  608. }
  609.     } else {
  610.         // device is unused!
  611.         PRINT_WARN ("Tape #%d was detached.n",ti->blk_minor/2);
  612.         if (ti==first_tape_info) {
  613.             first_tape_info=ti->next;
  614.         } else {
  615.             lastti=first_tape_info;
  616.             while (lastti->next!=ti) lastti=lastti->next;
  617.             lastti->next=ti->next;
  618.         }
  619. #ifdef CONFIG_DEVFS_FS
  620.         for (frontend=first_frontend;frontend!=NULL;frontend=frontend->next)
  621.             frontend->rmdevfstree(ti);
  622.         tape_rmdevfsroots(ti);
  623. #endif
  624.         kfree(ti);
  625.     }
  626.     s390irq_spin_unlock_irqrestore(irq,lockflags);
  627.     return;
  628. }
  629. void
  630. tape_dump_sense (devstat_t * stat)
  631. {
  632. #ifdef TAPE_DEBUG
  633.         int sl;
  634. #endif
  635. #if 0
  636. PRINT_WARN ("------------I/O resulted in unit check:-----------n");
  637. for (sl = 0; sl < 4; sl++) {
  638. PRINT_WARN ("Sense:");
  639. for (sct = 0; sct < 8; sct++) {
  640. PRINT_WARN (" %2d:0x%02X", 8 * sl + sct,
  641.     stat->ii.sense.data[8 * sl + sct]);
  642. }
  643. PRINT_WARN ("n");
  644. }
  645. PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
  646.     " %02X%02X%02X%02X %02X%02X%02X%02X n",
  647.     stat->ii.sense.data[0], stat->ii.sense.data[1],
  648.     stat->ii.sense.data[2], stat->ii.sense.data[3],
  649.     stat->ii.sense.data[4], stat->ii.sense.data[5],
  650.     stat->ii.sense.data[6], stat->ii.sense.data[7],
  651.     stat->ii.sense.data[8], stat->ii.sense.data[9],
  652.     stat->ii.sense.data[10], stat->ii.sense.data[11],
  653.     stat->ii.sense.data[12], stat->ii.sense.data[13],
  654.     stat->ii.sense.data[14], stat->ii.sense.data[15]);
  655. PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
  656.     " %02X%02X%02X%02X %02X%02X%02X%02X n",
  657.     stat->ii.sense.data[16], stat->ii.sense.data[17],
  658.     stat->ii.sense.data[18], stat->ii.sense.data[19],
  659.     stat->ii.sense.data[20], stat->ii.sense.data[21],
  660.     stat->ii.sense.data[22], stat->ii.sense.data[23],
  661.     stat->ii.sense.data[24], stat->ii.sense.data[25],
  662.     stat->ii.sense.data[26], stat->ii.sense.data[27],
  663.     stat->ii.sense.data[28], stat->ii.sense.data[29],
  664.     stat->ii.sense.data[30], stat->ii.sense.data[31]);
  665. #endif
  666. #ifdef TAPE_DEBUG
  667.         debug_text_event (tape_debug_area,3,"SENSE:");
  668.         for (sl=0;sl<31;sl++) {
  669.             debug_int_event (tape_debug_area,3,stat->ii.sense.data[sl]);
  670.         }
  671.         debug_int_exception (tape_debug_area,3,stat->ii.sense.data[31]);
  672. #endif
  673. }
  674. /*
  675.  * Setup tape_info_t structure of a tape device
  676.  */
  677. int
  678. tape_setup (tape_info_t * ti, int irq, int minor)
  679. {
  680. long lockflags;
  681. int rc = 0;
  682.         if (minor>254) {
  683.             PRINT_WARN ("Device id %d on irq %d will not be accessible since this driver is restricted to 128 devices.n",minor/2,irq);
  684.             return -EINVAL;
  685.         }
  686. rc = get_dev_info_by_irq (irq, &(ti->devinfo));
  687. if (rc == -ENODEV) { /* end of device list */
  688. return rc;
  689. }
  690. ti->rew_minor = minor;
  691. ti->nor_minor = minor + 1;
  692. ti->blk_minor = minor;
  693. #ifdef CONFIG_DEVFS_FS
  694.         tape_mkdevfsroots(ti);
  695. #endif
  696. /* Register IRQ */
  697. #ifdef CONFIG_S390_TAPE_DYNAMIC
  698.         rc = s390_request_irq_special (irq, tape_irq, tape_noper_handler,0, "tape", &(ti->devstat));
  699. #else
  700. rc = s390_request_irq (irq, tape_irq, 0, "tape", &(ti->devstat));
  701. #endif
  702. s390irq_spin_lock_irqsave (irq, lockflags);
  703. ti->next = NULL;
  704. if (rc)
  705.             PRINT_WARN ("Cannot register irq %d, rc=%dn", irq, rc);
  706. init_waitqueue_head (&ti->wq);
  707. ti->kernbuf = ti->userbuf = ti->discdata = NULL;
  708. tapestate_set (ti, TS_UNUSED);
  709.         ti->discdata=NULL;
  710. ti->discipline->setup_assist (ti);
  711.         ti->wanna_wakeup=0;
  712. s390irq_spin_unlock_irqrestore (irq, lockflags);
  713. return rc;
  714. }
  715. /*
  716.  *      tape_init will register the driver for each tape.
  717.  */
  718. int
  719. tape_init (void)
  720. {
  721. long lockflags;
  722. s390_dev_info_t dinfo;
  723. tape_discipline_t *disc;
  724. tape_info_t *ti = NULL, *tempti = NULL;
  725.         char *opt_char,*opt_block,*opt_3490,*opt_3480;
  726. int irq = 0, rc, retries = 0, tape_num = 0;
  727.         static int initialized=0;
  728.         if (initialized) // Only init the devices once
  729.             return 0;
  730.         initialized=1;
  731. #ifdef TAPE_DEBUG
  732.         tape_debug_area = debug_register ( "tape", 3, 2, 10);
  733.         debug_register_view(tape_debug_area,&debug_hex_ascii_view);
  734.         debug_text_event (tape_debug_area,3,"begin init");
  735. #endif /* TAPE_DEBUG */
  736.         /* print banner */        
  737.         PRINT_WARN ("IBM S/390 Tape Device Driver (v1.01).n");
  738.         PRINT_WARN ("(C) IBM Deutschland Entwicklung GmbH, 2000n");
  739.         opt_char=opt_block=opt_3480=opt_3490="not present";
  740. #ifdef CONFIG_S390_TAPE_CHAR
  741.         opt_char="built in";
  742. #endif
  743. #ifdef CONFIG_S390_TAPE_BLOCK
  744.         opt_block="built in";
  745. #endif
  746. #ifdef CONFIG_S390_TAPE_3480
  747.         opt_3480="built in";
  748. #endif
  749. #ifdef CONFIG_S390_TAPE_3490
  750.         opt_3490="built in";
  751. #endif
  752.         /* print feature info */
  753.         PRINT_WARN ("character device frontend   : %sn",opt_char);
  754.         PRINT_WARN ("block device frontend       : %sn",opt_block);
  755.         PRINT_WARN ("support for 3480 compatible : %sn",opt_3480);
  756.         PRINT_WARN ("support for 3490 compatible : %sn",opt_3490);
  757.         
  758. #ifndef MODULE
  759.         tape_split_parm_string(tape_parm_string);
  760. #endif
  761.         if (*tape) 
  762.             PRINT_INFO ("Using ranges supplied in parameters, disabling autoprobe mode.n");
  763.         else
  764.             PRINT_INFO ("No parameters supplied, enabling autoprobe mode for all supported devices.n");
  765. #ifdef CONFIG_S390_TAPE_3490
  766.         if (*tape)
  767.             first_discipline = tape3490_init (0); // no autoprobe for devices
  768.         else
  769.             first_discipline = tape3490_init (1); // do autoprobe since no parm specified
  770. first_discipline->next = NULL;
  771. #endif
  772. #ifdef CONFIG_S390_TAPE_3480
  773.         if (first_discipline == NULL) {
  774.             if (*tape)
  775.                 first_discipline = tape3480_init (0); // no autoprobe for devices
  776.             else 
  777.                 first_discipline = tape3480_init (1); // do autoprobe since no parm specified
  778.             first_discipline->next = NULL;
  779.         } else {
  780.             if (*tape)
  781.                 first_discipline->next = tape3480_init (0); // no autoprobe for devices
  782.             else
  783.                 first_discipline->next = tape3480_init (1); // do autoprobe since no parm specified
  784.             ((tape_discipline_t*) (first_discipline->next))->next=NULL;
  785.         }
  786. #endif
  787. #ifdef CONFIG_DEVFS_FS
  788.         tape_devfs_root_entry=devfs_mk_dir (NULL, "tape", NULL);
  789. #endif CONFIG_DEVFS_FS
  790. #ifdef TAPE_DEBUG
  791.         debug_text_event (tape_debug_area,3,"dev detect");
  792. #endif /* TAPE_DEBUG */
  793. /* Allocate the tape structures */
  794.         if (*tape!=NULL) {
  795.             // we have parameters, continue with parsing the parameters and set the devices online
  796.             tape_parm_parse (tape);
  797.         } else {
  798.             // we are running in autodetect mode, search all devices for compatibles
  799.             for (irq = get_irq_first(); irq!=-ENODEV; irq=get_irq_next(irq)) {
  800. rc = get_dev_info_by_irq (irq, &dinfo);
  801. disc = first_discipline;
  802. while ((disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))
  803.                     disc = (tape_discipline_t *) (disc->next);
  804. if ((disc == NULL) || (rc == -ENODEV))
  805.                     continue;
  806. #ifdef TAPE_DEBUG
  807.                 debug_text_event (tape_debug_area,3,"det irq:  ");
  808.                 debug_int_event (tape_debug_area,3,irq);
  809.                 debug_text_event (tape_debug_area,3,"cu:       ");
  810.                 debug_int_event (tape_debug_area,3,disc->cu_type);
  811. #endif /* TAPE_DEBUG */
  812.                 PRINT_INFO ("using devno %04x with discipline %04x on irq %d as tape device %dn",dinfo.devno,dinfo.sid_data.cu_type,irq,tape_num/2);
  813. /* Allocate tape structure  */
  814. ti = kmalloc (sizeof (tape_info_t), GFP_ATOMIC);
  815. if (ti == NULL) {
  816. #ifdef TAPE_DEBUG
  817.                     debug_text_exception (tape_debug_area,3,"ti:no mem ");
  818. #endif /* TAPE_DEBUG */
  819.                     PRINT_INFO ("tape: can't allocate memory for "
  820.     "tape info structuren");
  821.                     continue;
  822. }
  823. memset(ti,0,sizeof(tape_info_t));
  824. ti->discipline = disc;
  825. disc->tape = ti;
  826. rc = tape_setup (ti, irq, tape_num);
  827. if (rc) {
  828. #ifdef TAPE_DEBUG
  829.                     debug_text_event (tape_debug_area,3,"tsetup err");
  830.                     debug_int_exception (tape_debug_area,3,rc);
  831. #endif /* TAPE_DEBUG */
  832.                     kfree (ti);
  833. } else {
  834.                     s390irq_spin_lock_irqsave (irq, lockflags);
  835.                     if (first_tape_info == NULL) {
  836.                         first_tape_info = ti;
  837.                     } else {
  838.                         tempti = first_tape_info;
  839.                         while (tempti->next != NULL)
  840.                             tempti = tempti->next;
  841.                         tempti->next = ti;
  842.                     }
  843.                     tape_num += 2;
  844.                     s390irq_spin_unlock_irqrestore (irq, lockflags);
  845. }
  846.             }
  847.         }
  848.             
  849. /* Allocate local buffer for the ccwcache       */
  850. tape_init_emergency_req ();
  851. #ifdef CONFIG_PROC_FS
  852. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
  853. tape_devices_entry = create_proc_entry ("tapedevices",
  854. S_IFREG | S_IRUGO | S_IWUSR,
  855. &proc_root);
  856. tape_devices_entry->proc_fops = &tape_devices_file_ops;
  857. tape_devices_entry->proc_iops = &tape_devices_inode_ops;
  858. #else
  859. tape_devices_entry = (struct proc_dir_entry *) kmalloc 
  860.             (sizeof (struct proc_dir_entry), GFP_ATOMIC);
  861.         if (tape_devices_entry) {
  862.             memset (tape_devices_entry, 0, sizeof (struct proc_dir_entry));
  863.             tape_devices_entry->name = "tapedevices";
  864.             tape_devices_entry->namelen = strlen ("tapedevices");
  865.             tape_devices_entry->low_ino = 0;
  866.             tape_devices_entry->mode = (S_IFREG | S_IRUGO | S_IWUSR);
  867.             tape_devices_entry->nlink = 1;
  868.             tape_devices_entry->uid = 0;
  869.             tape_devices_entry->gid = 0;
  870.             tape_devices_entry->size = 0;
  871.             tape_devices_entry->get_info = NULL;
  872.             tape_devices_entry->ops = &tape_devices_inode_ops;
  873.             proc_register (&proc_root, tape_devices_entry);
  874. }
  875. #endif
  876. #endif /* CONFIG_PROC_FS */
  877. return 0;
  878. }
  879. #ifdef MODULE
  880. MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte (cotte@de.ibm.com)");
  881. MODULE_DESCRIPTION("Linux for S/390 channel attached tape device driver");
  882. MODULE_PARM (tape, "1-" __MODULE_STRING (256) "s");
  883. int
  884. init_module (void)
  885. {
  886. #ifdef CONFIG_S390_TAPE_CHAR
  887. tapechar_init ();
  888. #endif
  889. #ifdef CONFIG_S390_TAPE_BLOCK
  890. tapeblock_init ();
  891. #endif
  892.         return 0;
  893. }
  894. void
  895. cleanup_module (void)
  896. {
  897.         tape_info_t *ti ,*temp;
  898.         tape_frontend_t* frontend, *tempfe;
  899.         tape_discipline_t* disc ,*tempdi;
  900.         int i;
  901. #ifdef TAPE_DEBUG
  902.         debug_text_event (tape_debug_area,6,"cleaup mod");
  903. #endif /* TAPE_DEBUG */
  904.         if (*tape) {
  905.             // we are running with parameters. we'll now deregister from our devno's
  906.             for (i=0;i<devregct;i++) {
  907.                 s390_device_unregister(tape_devreg[devregct]);
  908.             }
  909.         }
  910. ti = first_tape_info;
  911. while (ti != NULL) {
  912. temp = ti;
  913. ti = ti->next;
  914.                 //cleanup a device 
  915. #ifdef TAPE_DEBUG
  916.                 debug_text_event (tape_debug_area,6,"free irq:");
  917.                 debug_int_event (tape_debug_area,6,temp->devinfo.irq);
  918. #endif /* TAPE_DEBUG */
  919. free_irq (temp->devinfo.irq, &(temp->devstat));
  920.                 if (temp->discdata) kfree (temp->discdata);
  921.                 if (temp->kernbuf) kfree (temp->kernbuf);
  922.                 if (temp->cqr) tape_free_request(temp->cqr);
  923. #ifdef CONFIG_DEVFS_FS
  924.                 for (frontend=first_frontend;frontend!=NULL;frontend=frontend->next)
  925.                     frontend->rmdevfstree(temp);
  926.                 tape_rmdevfsroots(temp);
  927. #endif
  928. kfree (temp);
  929. }
  930. #ifdef CONFIG_DEVFS_FS
  931.         devfs_unregister (tape_devfs_root_entry);
  932. #endif CONFIG_DEVFS_FS
  933. #ifdef CONFIG_PROC_FS
  934. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
  935. remove_proc_entry ("tapedevices", &proc_root);
  936. #else
  937. proc_unregister (&proc_root, tape_devices_entry->low_ino);
  938. kfree (tape_devices_entry);
  939. #endif /* LINUX_IS_24 */
  940. #endif 
  941. #ifdef CONFIG_S390_TAPE_CHAR
  942. tapechar_uninit();
  943. #endif
  944. #ifdef CONFIG_S390_TAPE_BLOCK
  945.         tapeblock_uninit();
  946. #endif
  947.         frontend=first_frontend;
  948. while (frontend != NULL) {
  949. tempfe = frontend;
  950. frontend = frontend->next;
  951. kfree (tempfe);
  952. }
  953.         disc=first_discipline;
  954. while (disc != NULL) {
  955.                 if (*tape)
  956.                     disc->shutdown(0);
  957.                 else
  958.                     disc->shutdown(1);
  959. tempdi = disc;
  960. disc = disc->next;
  961. kfree (tempdi);
  962. }
  963. /* Deallocate the local buffer for the ccwcache         */
  964. tape_cleanup_emergency_req ();
  965. #ifdef TAPE_DEBUG
  966.         debug_unregister (tape_debug_area);
  967. #endif /* TAPE_DEBUG */
  968. }
  969. #endif /* MODULE */
  970. inline void
  971. tapestate_set (tape_info_t * ti, int newstate)
  972. {
  973.     if (ti->tape_state == TS_NOT_OPER) {
  974. #ifdef TAPE_DEBUG
  975.         debug_text_event (tape_debug_area,3,"ts_set err");
  976.         debug_text_exception (tape_debug_area,3,"dev n.oper");
  977. #endif /* TAPE_DEBUG */
  978.     } else {
  979. #ifdef TAPE_DEBUG
  980.         debug_text_event (tape_debug_area,4,"ts. dev:  ");
  981.         debug_int_event (tape_debug_area,4,ti->blk_minor);
  982.         debug_text_event (tape_debug_area,4,"old ts:   ");
  983.         debug_text_event (tape_debug_area,4,(((tapestate_get (ti) < TS_SIZE) &&
  984.                                              (tapestate_get (ti) >=0 )) ?
  985.                                             state_verbose[tapestate_get (ti)] :
  986.                                             "UNKNOWN TS"));
  987.         debug_text_event (tape_debug_area,4,"new ts:   ");
  988.         debug_text_event (tape_debug_area,4,(((newstate < TS_SIZE) &&
  989.                                               (newstate >= 0)) ?
  990.                                              state_verbose[newstate] :
  991.                                              "UNKNOWN TS"));
  992. #endif /* TAPE_DEBUG */
  993. ti->tape_state = newstate;
  994.     }
  995. }
  996. inline int
  997. tapestate_get (tape_info_t * ti)
  998. {
  999. return (ti->tape_state);
  1000. }
  1001. void
  1002. tapestate_event (tape_info_t * ti, int event)
  1003. {
  1004. #ifdef TAPE_DEBUG
  1005.         debug_text_event (tape_debug_area,6,"te! dev:  ");
  1006.         debug_int_event (tape_debug_area,6,ti->blk_minor);
  1007.         debug_text_event (tape_debug_area,6,"event:");
  1008.         debug_text_event (tape_debug_area,6,((event >=0) &&
  1009.                                             (event < TE_SIZE)) ?
  1010.                          event_verbose[event] : "TE UNKNOWN");
  1011.         debug_text_event (tape_debug_area,6,"state:");
  1012.         debug_text_event (tape_debug_area,6,((tapestate_get(ti) >= 0) &&
  1013.                                             (tapestate_get(ti) < TS_SIZE)) ?
  1014.                          state_verbose[tapestate_get (ti)] :
  1015.                          "TS UNKNOWN");
  1016. #endif /* TAPE_DEBUG */    
  1017.         if (event == TE_ERROR) { 
  1018.             ti->discipline->error_recovery(ti);
  1019.         } else {
  1020.             if ((event >= 0) &&
  1021.                 (event < TE_SIZE) &&
  1022.                 (tapestate_get (ti) >= 0) &&
  1023.                 (tapestate_get (ti) < TS_SIZE) &&
  1024.                 ((*(ti->discipline->event_table))[tapestate_get (ti)][event] != NULL))
  1025. ((*(ti->discipline->event_table))[tapestate_get (ti)][event]) (ti);
  1026.             else {
  1027. #ifdef TAPE_DEBUG
  1028.                 debug_text_exception (tape_debug_area,3,"TE UNEXPEC");
  1029. #endif /* TAPE_DEBUG */
  1030. ti->discipline->default_handler (ti);
  1031.             }
  1032.         }
  1033. }
  1034. /*
  1035.  * Overrides for Emacs so that we follow Linus's tabbing style.
  1036.  * Emacs will notice this stuff at the end of the file and automatically
  1037.  * adjust the settings for this buffer only.  This must remain at the end
  1038.  * of the file.
  1039.  * ---------------------------------------------------------------------------
  1040.  * Local variables:
  1041.  * c-indent-level: 4
  1042.  * c-brace-imaginary-offset: 0
  1043.  * c-brace-offset: -4
  1044.  * c-argdecl-indent: 4
  1045.  * c-label-offset: -4
  1046.  * c-continued-statement-offset: 4
  1047.  * c-continued-brace-offset: 0
  1048.  * indent-tabs-mode: nil
  1049.  * tab-width: 8
  1050.  * End:
  1051.  */