Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
device_ops.c
Go to the documentation of this file.
1 /*
2  * Copyright IBM Corp. 2002, 2009
3  *
4  * Author(s): Martin Schwidefsky ([email protected])
5  * Cornelia Huck ([email protected])
6  */
7 #include <linux/module.h>
8 #include <linux/init.h>
9 #include <linux/errno.h>
10 #include <linux/slab.h>
11 #include <linux/list.h>
12 #include <linux/device.h>
13 #include <linux/delay.h>
14 #include <linux/completion.h>
15 
16 #include <asm/ccwdev.h>
17 #include <asm/idals.h>
18 #include <asm/chpid.h>
19 #include <asm/fcx.h>
20 
21 #include "cio.h"
22 #include "cio_debug.h"
23 #include "css.h"
24 #include "chsc.h"
25 #include "device.h"
26 #include "chp.h"
27 
38 int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)
39 {
40  /*
41  * The flag usage is mutal exclusive ...
42  */
43  if ((flags & CCWDEV_EARLY_NOTIFICATION) &&
44  (flags & CCWDEV_REPORT_ALL))
45  return -EINVAL;
46  cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
47  cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
48  cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
49  cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
50  cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
51  return 0;
52 }
53 
63 int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
64 {
65  /*
66  * The flag usage is mutal exclusive ...
67  */
68  if (((flags & CCWDEV_EARLY_NOTIFICATION) &&
69  (flags & CCWDEV_REPORT_ALL)) ||
70  ((flags & CCWDEV_EARLY_NOTIFICATION) &&
71  cdev->private->options.repall) ||
72  ((flags & CCWDEV_REPORT_ALL) &&
73  cdev->private->options.fast))
74  return -EINVAL;
75  cdev->private->options.fast |= (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
76  cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
77  cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
78  cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
79  cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
80  return 0;
81 }
82 
90 void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)
91 {
92  cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0;
93  cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
94  cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
95  cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
96  cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
97 }
98 
106 {
107  return cdev->private->flags.pgroup;
108 }
110 
118 {
119  return cdev->private->flags.mpath;
120 }
122 
138 int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
139 {
140  struct subchannel *sch;
141  int ret;
142 
143  if (!cdev || !cdev->dev.parent)
144  return -ENODEV;
145  sch = to_subchannel(cdev->dev.parent);
146  if (!sch->schib.pmcw.ena)
147  return -EINVAL;
148  if (cdev->private->state == DEV_STATE_NOT_OPER)
149  return -ENODEV;
150  if (cdev->private->state != DEV_STATE_ONLINE &&
151  cdev->private->state != DEV_STATE_W4SENSE)
152  return -EINVAL;
153 
154  ret = cio_clear(sch);
155  if (ret == 0)
156  cdev->private->intparm = intparm;
157  return ret;
158 }
159 
185  unsigned long intparm, __u8 lpm, __u8 key,
186  unsigned long flags)
187 {
188  struct subchannel *sch;
189  int ret;
190 
191  if (!cdev || !cdev->dev.parent)
192  return -ENODEV;
193  sch = to_subchannel(cdev->dev.parent);
194  if (!sch->schib.pmcw.ena)
195  return -EINVAL;
196  if (cdev->private->state == DEV_STATE_NOT_OPER)
197  return -ENODEV;
198  if (cdev->private->state == DEV_STATE_VERIFY) {
199  /* Remember to fake irb when finished. */
200  if (!cdev->private->flags.fake_irb) {
201  cdev->private->flags.fake_irb = FAKE_CMD_IRB;
202  cdev->private->intparm = intparm;
203  return 0;
204  } else
205  /* There's already a fake I/O around. */
206  return -EBUSY;
207  }
208  if (cdev->private->state != DEV_STATE_ONLINE ||
209  ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&
210  !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) ||
211  cdev->private->flags.doverify)
212  return -EBUSY;
213  ret = cio_set_options (sch, flags);
214  if (ret)
215  return ret;
216  /* Adjust requested path mask to exclude unusable paths. */
217  if (lpm) {
218  lpm &= sch->lpm;
219  if (lpm == 0)
220  return -EACCES;
221  }
222  ret = cio_start_key (sch, cpa, lpm, key);
223  switch (ret) {
224  case 0:
225  cdev->private->intparm = intparm;
226  break;
227  case -EACCES:
228  case -ENODEV:
229  dev_fsm_event(cdev, DEV_EVENT_VERIFY);
230  break;
231  }
232  return ret;
233 }
234 
265  unsigned long intparm, __u8 lpm, __u8 key,
266  unsigned long flags, int expires)
267 {
268  int ret;
269 
270  if (!cdev)
271  return -ENODEV;
272  ccw_device_set_timeout(cdev, expires);
273  ret = ccw_device_start_key(cdev, cpa, intparm, lpm, key, flags);
274  if (ret != 0)
275  ccw_device_set_timeout(cdev, 0);
276  return ret;
277 }
278 
302 int ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
303  unsigned long intparm, __u8 lpm, unsigned long flags)
304 {
305  return ccw_device_start_key(cdev, cpa, intparm, lpm,
306  PAGE_DEFAULT_KEY, flags);
307 }
308 
338  unsigned long intparm, __u8 lpm,
339  unsigned long flags, int expires)
340 {
341  return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
342  PAGE_DEFAULT_KEY, flags,
343  expires);
344 }
345 
346 
363 int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
364 {
365  struct subchannel *sch;
366  int ret;
367 
368  if (!cdev || !cdev->dev.parent)
369  return -ENODEV;
370  sch = to_subchannel(cdev->dev.parent);
371  if (!sch->schib.pmcw.ena)
372  return -EINVAL;
373  if (cdev->private->state == DEV_STATE_NOT_OPER)
374  return -ENODEV;
375  if (cdev->private->state != DEV_STATE_ONLINE &&
376  cdev->private->state != DEV_STATE_W4SENSE)
377  return -EINVAL;
378 
379  ret = cio_halt(sch);
380  if (ret == 0)
381  cdev->private->intparm = intparm;
382  return ret;
383 }
384 
399 {
400  struct subchannel *sch;
401 
402  if (!cdev || !cdev->dev.parent)
403  return -ENODEV;
404  sch = to_subchannel(cdev->dev.parent);
405  if (!sch->schib.pmcw.ena)
406  return -EINVAL;
407  if (cdev->private->state == DEV_STATE_NOT_OPER)
408  return -ENODEV;
409  if (cdev->private->state != DEV_STATE_ONLINE ||
410  !(sch->schib.scsw.cmd.actl & SCSW_ACTL_SUSPENDED))
411  return -EINVAL;
412  return cio_resume(sch);
413 }
414 
415 /*
416  * Pass interrupt to device driver.
417  */
418 int
420 {
421  unsigned int stctl;
422  int ending_status;
423 
424  /*
425  * we allow for the device action handler if .
426  * - we received ending status
427  * - the action handler requested to see all interrupts
428  * - we received an intermediate status
429  * - fast notification was requested (primary status)
430  * - unsolicited interrupts
431  */
432  stctl = scsw_stctl(&cdev->private->irb.scsw);
433  ending_status = (stctl & SCSW_STCTL_SEC_STATUS) ||
435  (stctl == SCSW_STCTL_STATUS_PEND);
436  if (!ending_status &&
437  !cdev->private->options.repall &&
438  !(stctl & SCSW_STCTL_INTER_STATUS) &&
439  !(cdev->private->options.fast &&
440  (stctl & SCSW_STCTL_PRIM_STATUS)))
441  return 0;
442 
443  /* Clear pending timers for device driver initiated I/O. */
444  if (ending_status)
445  ccw_device_set_timeout(cdev, 0);
446  /*
447  * Now we are ready to call the device driver interrupt handler.
448  */
449  if (cdev->handler)
450  cdev->handler(cdev, cdev->private->intparm,
451  &cdev->private->irb);
452 
453  /*
454  * Clear the old and now useless interrupt response block.
455  */
456  memset(&cdev->private->irb, 0, sizeof(struct irb));
457 
458  return 1;
459 }
460 
476 {
477  int ciw_cnt;
478 
479  if (cdev->private->flags.esid == 0)
480  return NULL;
481  for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++)
482  if (cdev->private->senseid.ciw[ciw_cnt].ct == ct)
483  return cdev->private->senseid.ciw + ciw_cnt;
484  return NULL;
485 }
486 
495 {
496  struct subchannel *sch;
497 
498  if (!cdev->dev.parent)
499  return 0;
500 
501  sch = to_subchannel(cdev->dev.parent);
502  return sch->lpm;
503 }
504 
505 struct stlck_data {
506  struct completion done;
507  int rc;
508 };
509 
510 void ccw_device_stlck_done(struct ccw_device *cdev, void *data, int rc)
511 {
512  struct stlck_data *sdata = data;
513 
514  sdata->rc = rc;
515  complete(&sdata->done);
516 }
517 
518 /*
519  * Perform unconditional reserve + release.
520  */
522 {
523  struct subchannel *sch = to_subchannel(cdev->dev.parent);
524  struct stlck_data data;
525  u8 *buffer;
526  int rc;
527 
528  /* Check if steal lock operation is valid for this device. */
529  if (cdev->drv) {
530  if (!cdev->private->options.force)
531  return -EINVAL;
532  }
533  buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
534  if (!buffer)
535  return -ENOMEM;
536  init_completion(&data.done);
537  data.rc = -EIO;
538  spin_lock_irq(sch->lock);
539  rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
540  if (rc)
541  goto out_unlock;
542  /* Perform operation. */
543  cdev->private->state = DEV_STATE_STEAL_LOCK,
544  ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
545  spin_unlock_irq(sch->lock);
546  /* Wait for operation to finish. */
548  /* Got a signal. */
549  spin_lock_irq(sch->lock);
550  ccw_request_cancel(cdev);
551  spin_unlock_irq(sch->lock);
552  wait_for_completion(&data.done);
553  }
554  rc = data.rc;
555  /* Check results. */
556  spin_lock_irq(sch->lock);
558  cdev->private->state = DEV_STATE_BOXED;
559 out_unlock:
560  spin_unlock_irq(sch->lock);
561  kfree(buffer);
562 
563  return rc;
564 }
565 
566 void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
567 {
568  struct subchannel *sch;
569  struct chp_id chpid;
570 
571  sch = to_subchannel(cdev->dev.parent);
572  chp_id_init(&chpid);
573  chpid.id = sch->schib.pmcw.chpid[chp_no];
574  return chp_get_chp_desc(chpid);
575 }
576 
583 {
584  *dev_id = cdev->private->dev_id;
585 }
587 
600  unsigned long intparm, u8 lpm, u8 key)
601 {
602  struct subchannel *sch;
603  int rc;
604 
605  sch = to_subchannel(cdev->dev.parent);
606  if (!sch->schib.pmcw.ena)
607  return -EINVAL;
608  if (cdev->private->state == DEV_STATE_VERIFY) {
609  /* Remember to fake irb when finished. */
610  if (!cdev->private->flags.fake_irb) {
611  cdev->private->flags.fake_irb = FAKE_TM_IRB;
612  cdev->private->intparm = intparm;
613  return 0;
614  } else
615  /* There's already a fake I/O around. */
616  return -EBUSY;
617  }
618  if (cdev->private->state != DEV_STATE_ONLINE)
619  return -EIO;
620  /* Adjust requested path mask to exclude unusable paths. */
621  if (lpm) {
622  lpm &= sch->lpm;
623  if (lpm == 0)
624  return -EACCES;
625  }
626  rc = cio_tm_start_key(sch, tcw, lpm, key);
627  if (rc == 0)
628  cdev->private->intparm = intparm;
629  return rc;
630 }
632 
646  unsigned long intparm, u8 lpm, u8 key,
647  int expires)
648 {
649  int ret;
650 
651  ccw_device_set_timeout(cdev, expires);
652  ret = ccw_device_tm_start_key(cdev, tcw, intparm, lpm, key);
653  if (ret != 0)
654  ccw_device_set_timeout(cdev, 0);
655  return ret;
656 }
658 
670  unsigned long intparm, u8 lpm)
671 {
672  return ccw_device_tm_start_key(cdev, tcw, intparm, lpm,
674 }
676 
689  unsigned long intparm, u8 lpm, int expires)
690 {
691  return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm,
692  PAGE_DEFAULT_KEY, expires);
693 }
695 
705 {
706  struct subchannel *sch = to_subchannel(cdev->dev.parent);
707  struct channel_path_desc_fmt1 desc;
708  struct chp_id chpid;
709  int mdc = 0, ret, i;
710 
711  /* Adjust requested path mask to excluded varied off paths. */
712  if (mask)
713  mask &= sch->lpm;
714  else
715  mask = sch->lpm;
716 
717  chp_id_init(&chpid);
718  for (i = 0; i < 8; i++) {
719  if (!(mask & (0x80 >> i)))
720  continue;
721  chpid.id = sch->schib.pmcw.chpid[i];
723  if (ret)
724  return ret;
725  if (!desc.f)
726  return 0;
727  if (!desc.r)
728  mdc = 1;
729  mdc = mdc ? min(mdc, (int)desc.mdc) : desc.mdc;
730  }
731 
732  return mdc;
733 }
735 
744 {
745  struct subchannel *sch = to_subchannel(cdev->dev.parent);
746 
747  if (!sch->schib.pmcw.ena)
748  return -EINVAL;
749  if (cdev->private->state != DEV_STATE_ONLINE)
750  return -EIO;
751  if (!scsw_is_tm(&sch->schib.scsw) ||
752  !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
753  return -EINVAL;
754  return cio_tm_intrg(sch);
755 }
757 
758 // FIXME: these have to go:
759 
760 int
762 {
763  return cdev->private->schid.sch_no;
764 }
765 
766 
767 MODULE_LICENSE("GPL");