Pull pnpacpi into acpica branch
[linux-2.6] / drivers / s390 / block / dasd_diag.c
1 /* 
2  * File...........: linux/drivers/s390/block/dasd_diag.c
3  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4  * Based on.......: linux/drivers/s390/block/mdisk.c
5  * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
6  * Bugreports.to..: <Linux390@de.ibm.com>
7  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
8  *
9  * $Revision: 1.53 $
10  */
11
12 #include <linux/config.h>
13 #include <linux/stddef.h>
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/hdreg.h>
17 #include <linux/bio.h>
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/jiffies.h>
21
22 #include <asm/dasd.h>
23 #include <asm/debug.h>
24 #include <asm/ebcdic.h>
25 #include <asm/io.h>
26 #include <asm/s390_ext.h>
27 #include <asm/todclk.h>
28 #include <asm/vtoc.h>
29
30 #include "dasd_int.h"
31 #include "dasd_diag.h"
32
33 #define PRINTK_HEADER "dasd(diag):"
34
35 MODULE_LICENSE("GPL");
36
37 /* The maximum number of blocks per request (max_blocks) is dependent on the
38  * amount of storage that is available in the static I/O buffer for each
39  * device. Currently each device gets 2 pages. We want to fit two requests
40  * into the available memory so that we can immediately start the next if one
41  * finishes. */
42 #define DIAG_MAX_BLOCKS (((2 * PAGE_SIZE - sizeof(struct dasd_ccw_req) - \
43                            sizeof(struct dasd_diag_req)) / \
44                            sizeof(struct dasd_diag_bio)) / 2)
45 #define DIAG_MAX_RETRIES        32
46 #define DIAG_TIMEOUT            50 * HZ
47
48 struct dasd_discipline dasd_diag_discipline;
49
50 struct dasd_diag_private {
51         struct dasd_diag_characteristics rdc_data;
52         struct dasd_diag_rw_io iob;
53         struct dasd_diag_init_io iib;
54         blocknum_t pt_block;
55 };
56
57 struct dasd_diag_req {
58         unsigned int block_count;
59         struct dasd_diag_bio bio[0];
60 };
61
62 static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
63
64 /* Perform DIAG250 call with block I/O parameter list iob (input and output)
65  * and function code cmd.
66  * In case of an exception return 3. Otherwise return result of bitwise OR of
67  * resulting condition code and DIAG return code. */
68 static __inline__ int
69 dia250(void *iob, int cmd)
70 {
71         typedef union {
72                 struct dasd_diag_init_io init_io;
73                 struct dasd_diag_rw_io rw_io;
74         } addr_type;
75         int rc;
76
77         __asm__ __volatile__(
78 #ifdef CONFIG_64BIT
79                 "       lghi    %0,3\n"
80                 "       lgr     0,%3\n"
81                 "       diag    0,%2,0x250\n"
82                 "0:     ipm     %0\n"
83                 "       srl     %0,28\n"
84                 "       or      %0,1\n"
85                 "1:\n"
86                 ".section __ex_table,\"a\"\n"
87                 "       .align 8\n"
88                 "       .quad  0b,1b\n"
89                 ".previous\n"
90 #else
91                 "       lhi     %0,3\n"
92                 "       lr      0,%3\n"
93                 "       diag    0,%2,0x250\n"
94                 "0:     ipm     %0\n"
95                 "       srl     %0,28\n"
96                 "       or      %0,1\n"
97                 "1:\n"
98                 ".section __ex_table,\"a\"\n"
99                 "       .align 4\n"
100                 "       .long 0b,1b\n"
101                 ".previous\n"
102 #endif
103                 : "=&d" (rc), "=m" (*(addr_type *) iob)
104                 : "d" (cmd), "d" (iob), "m" (*(addr_type *) iob)
105                 : "0", "1", "cc");
106         return rc;
107 }
108
109 /* Initialize block I/O to DIAG device using the specified blocksize and
110  * block offset. On success, return zero and set end_block to contain the
111  * number of blocks on the device minus the specified offset. Return non-zero
112  * otherwise. */
113 static __inline__ int
114 mdsk_init_io(struct dasd_device *device, unsigned int blocksize,
115              blocknum_t offset, blocknum_t *end_block)
116 {
117         struct dasd_diag_private *private;
118         struct dasd_diag_init_io *iib;
119         int rc;
120
121         private = (struct dasd_diag_private *) device->private;
122         iib = &private->iib;
123         memset(iib, 0, sizeof (struct dasd_diag_init_io));
124
125         iib->dev_nr = _ccw_device_get_device_number(device->cdev);
126         iib->block_size = blocksize;
127         iib->offset = offset;
128         iib->flaga = DASD_DIAG_FLAGA_DEFAULT;
129
130         rc = dia250(iib, INIT_BIO);
131
132         if ((rc & 3) == 0 && end_block)
133                 *end_block = iib->end_block;
134
135         return rc;
136 }
137
138 /* Remove block I/O environment for device. Return zero on success, non-zero
139  * otherwise. */
140 static __inline__ int
141 mdsk_term_io(struct dasd_device * device)
142 {
143         struct dasd_diag_private *private;
144         struct dasd_diag_init_io *iib;
145         int rc;
146
147         private = (struct dasd_diag_private *) device->private;
148         iib = &private->iib;
149         memset(iib, 0, sizeof (struct dasd_diag_init_io));
150         iib->dev_nr = _ccw_device_get_device_number(device->cdev);
151         rc = dia250(iib, TERM_BIO);
152         return rc;
153 }
154
155 /* Error recovery for failed DIAG requests - try to reestablish the DIAG
156  * environment. */
157 static void
158 dasd_diag_erp(struct dasd_device *device)
159 {
160         int rc;
161
162         mdsk_term_io(device);
163         rc = mdsk_init_io(device, device->bp_block, 0, NULL);
164         if (rc)
165                 DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, "
166                             "rc=%d", rc);
167 }
168
169 /* Start a given request at the device. Return zero on success, non-zero
170  * otherwise. */
171 static int
172 dasd_start_diag(struct dasd_ccw_req * cqr)
173 {
174         struct dasd_device *device;
175         struct dasd_diag_private *private;
176         struct dasd_diag_req *dreq;
177         int rc;
178
179         device = cqr->device;
180         if (cqr->retries < 0) {
181                 DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p "
182                             "- no retry left)", cqr);
183                 cqr->status = DASD_CQR_FAILED;
184                 return -EIO;
185         }
186         private = (struct dasd_diag_private *) device->private;
187         dreq = (struct dasd_diag_req *) cqr->data;
188
189         private->iob.dev_nr = _ccw_device_get_device_number(device->cdev);
190         private->iob.key = 0;
191         private->iob.flags = DASD_DIAG_RWFLAG_ASYNC;
192         private->iob.block_count = dreq->block_count;
193         private->iob.interrupt_params = (addr_t) cqr;
194         private->iob.bio_list = dreq->bio;
195         private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
196
197         cqr->startclk = get_clock();
198         cqr->starttime = jiffies;
199         cqr->retries--;
200
201         rc = dia250(&private->iob, RW_BIO);
202         switch (rc) {
203         case 0: /* Synchronous I/O finished successfully */
204                 cqr->stopclk = get_clock();
205                 cqr->status = DASD_CQR_DONE;
206                 /* Indicate to calling function that only a dasd_schedule_bh()
207                    and no timer is needed */
208                 rc = -EACCES;
209                 break;
210         case 8: /* Asynchronous I/O was started */
211                 cqr->status = DASD_CQR_IN_IO;
212                 rc = 0;
213                 break;
214         default: /* Error condition */
215                 cqr->status = DASD_CQR_QUEUED;
216                 DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc);
217                 dasd_diag_erp(device);
218                 rc = -EIO;
219                 break;
220         }
221         return rc;
222 }
223
224 /* Terminate given request at the device. */
225 static int
226 dasd_diag_term_IO(struct dasd_ccw_req * cqr)
227 {
228         struct dasd_device *device;
229
230         device = cqr->device;
231         mdsk_term_io(device);
232         mdsk_init_io(device, device->bp_block, 0, NULL);
233         cqr->status = DASD_CQR_CLEAR;
234         cqr->stopclk = get_clock();
235         dasd_schedule_bh(device);
236         return 0;
237 }
238
239 /* Handle external interruption. */
240 static void
241 dasd_ext_handler(struct pt_regs *regs, __u16 code)
242 {
243         struct dasd_ccw_req *cqr, *next;
244         struct dasd_device *device;
245         unsigned long long expires;
246         unsigned long flags;
247         u8 int_code, status;
248         addr_t ip;
249         int rc;
250
251         int_code = *((u8 *) DASD_DIAG_LC_INT_CODE);
252         status = *((u8 *) DASD_DIAG_LC_INT_STATUS);
253         switch (int_code) {
254         case DASD_DIAG_CODE_31BIT:
255                 ip = (addr_t) *((u32 *) DASD_DIAG_LC_INT_PARM_31BIT);
256                 break;
257         case DASD_DIAG_CODE_64BIT:
258                 ip = (addr_t) *((u64 *) DASD_DIAG_LC_INT_PARM_64BIT);
259                 break;
260         default:
261                 return;
262         }
263         if (!ip) {              /* no intparm: unsolicited interrupt */
264                 MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
265                 return;
266         }
267         cqr = (struct dasd_ccw_req *) ip;
268         device = (struct dasd_device *) cqr->device;
269         if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
270                 DEV_MESSAGE(KERN_WARNING, device,
271                             " magic number of dasd_ccw_req 0x%08X doesn't"
272                             " match discipline 0x%08X",
273                             cqr->magic, *(int *) (&device->discipline->name));
274                 return;
275         }
276
277         /* get irq lock to modify request queue */
278         spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
279
280         /* Check for a pending clear operation */
281         if (cqr->status == DASD_CQR_CLEAR) {
282                 cqr->status = DASD_CQR_QUEUED;
283                 dasd_clear_timer(device);
284                 dasd_schedule_bh(device);
285                 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
286                 return;
287         }
288
289         cqr->stopclk = get_clock();
290
291         expires = 0;
292         if (status == 0) {
293                 cqr->status = DASD_CQR_DONE;
294                 /* Start first request on queue if possible -> fast_io. */
295                 if (!list_empty(&device->ccw_queue)) {
296                         next = list_entry(device->ccw_queue.next,
297                                           struct dasd_ccw_req, list);
298                         if (next->status == DASD_CQR_QUEUED) {
299                                 rc = dasd_start_diag(next);
300                                 if (rc == 0)
301                                         expires = next->expires;
302                                 else if (rc != -EACCES)
303                                         DEV_MESSAGE(KERN_WARNING, device, "%s",
304                                                     "Interrupt fastpath "
305                                                     "failed!");
306                         }
307                 }
308         } else {
309                 cqr->status = DASD_CQR_QUEUED;
310                 DEV_MESSAGE(KERN_WARNING, device, "interrupt status for "
311                             "request %p was %d (%d retries left)", cqr, status,
312                             cqr->retries);
313                 dasd_diag_erp(device);
314         }
315
316         if (expires != 0)
317                 dasd_set_timer(device, expires);
318         else
319                 dasd_clear_timer(device);
320         dasd_schedule_bh(device);
321
322         spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
323 }
324
325 /* Check whether device can be controlled by DIAG discipline. Return zero on
326  * success, non-zero otherwise. */
327 static int
328 dasd_diag_check_device(struct dasd_device *device)
329 {
330         struct dasd_diag_private *private;
331         struct dasd_diag_characteristics *rdc_data;
332         struct dasd_diag_bio bio;
333         struct vtoc_cms_label *label;
334         blocknum_t end_block;
335         unsigned int sb, bsize;
336         int rc;
337
338         private = (struct dasd_diag_private *) device->private;
339         if (private == NULL) {
340                 private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
341                 if (private == NULL) {
342                         DEV_MESSAGE(KERN_WARNING, device, "%s",
343                                 "memory allocation failed for private data");
344                         return -ENOMEM;
345                 }
346                 device->private = (void *) private;
347         }
348         /* Read Device Characteristics */
349         rdc_data = (void *) &(private->rdc_data);
350         rdc_data->dev_nr = _ccw_device_get_device_number(device->cdev);
351         rdc_data->rdc_len = sizeof (struct dasd_diag_characteristics);
352
353         rc = diag210((struct diag210 *) rdc_data);
354         if (rc) {
355                 DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device "
356                             "information (rc=%d)", rc);
357                 return -ENOTSUPP;
358         }
359
360         /* Figure out position of label block */
361         switch (private->rdc_data.vdev_class) {
362         case DEV_CLASS_FBA:
363                 private->pt_block = 1;
364                 break;
365         case DEV_CLASS_ECKD:
366                 private->pt_block = 2;
367                 break;
368         default:
369                 DEV_MESSAGE(KERN_WARNING, device, "unsupported device class "
370                             "(class=%d)", private->rdc_data.vdev_class);
371                 return -ENOTSUPP;
372         }
373
374         DBF_DEV_EVENT(DBF_INFO, device,
375                       "%04X: %04X on real %04X/%02X",
376                       rdc_data->dev_nr,
377                       rdc_data->vdev_type,
378                       rdc_data->rdev_type, rdc_data->rdev_model);
379
380         /* terminate all outstanding operations */
381         mdsk_term_io(device);
382
383         /* figure out blocksize of device */
384         label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
385         if (label == NULL)  {
386                 DEV_MESSAGE(KERN_WARNING, device, "%s",
387                             "No memory to allocate initialization request");
388                 return -ENOMEM;
389         }
390         rc = 0;
391         end_block = 0;
392         /* try all sizes - needed for ECKD devices */
393         for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) {
394                 mdsk_init_io(device, bsize, 0, &end_block);
395                 memset(&bio, 0, sizeof (struct dasd_diag_bio));
396                 bio.type = MDSK_READ_REQ;
397                 bio.block_number = private->pt_block + 1;
398                 bio.buffer = label;
399                 memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
400                 private->iob.dev_nr = rdc_data->dev_nr;
401                 private->iob.key = 0;
402                 private->iob.flags = 0; /* do synchronous io */
403                 private->iob.block_count = 1;
404                 private->iob.interrupt_params = 0;
405                 private->iob.bio_list = &bio;
406                 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
407                 rc = dia250(&private->iob, RW_BIO);
408                 if (rc == 3) {
409                         DEV_MESSAGE(KERN_WARNING, device, "%s",
410                                 "DIAG call failed");
411                         rc = -EOPNOTSUPP;
412                         goto out;
413                 }
414                 mdsk_term_io(device);
415                 if (rc == 0)
416                         break;
417         }
418         if (bsize > PAGE_SIZE) {
419                 DEV_MESSAGE(KERN_WARNING, device, "device access failed "
420                             "(rc=%d)", rc);
421                 rc = -EIO;
422                 goto out;
423         }
424         /* check for label block */
425         if (memcmp(label->label_id, DASD_DIAG_CMS1,
426                   sizeof(DASD_DIAG_CMS1)) == 0) {
427                 /* get formatted blocksize from label block */
428                 bsize = (unsigned int) label->block_size;
429                 device->blocks = (unsigned long) label->block_count;
430         } else
431                 device->blocks = end_block;
432         device->bp_block = bsize;
433         device->s2b_shift = 0;  /* bits to shift 512 to get a block */
434         for (sb = 512; sb < bsize; sb = sb << 1)
435                 device->s2b_shift++;
436         rc = mdsk_init_io(device, device->bp_block, 0, NULL);
437         if (rc) {
438                 DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
439                         "failed (rc=%d)", rc);
440                 rc = -EIO;
441         } else {
442                 DEV_MESSAGE(KERN_INFO, device,
443                             "(%ld B/blk): %ldkB",
444                             (unsigned long) device->bp_block,
445                             (unsigned long) (device->blocks <<
446                                 device->s2b_shift) >> 1);
447         }
448 out:
449         free_page((long) label);
450         return rc;
451 }
452
453 /* Fill in virtual disk geometry for device. Return zero on success, non-zero
454  * otherwise. */
455 static int
456 dasd_diag_fill_geometry(struct dasd_device *device, struct hd_geometry *geo)
457 {
458         if (dasd_check_blocksize(device->bp_block) != 0)
459                 return -EINVAL;
460         geo->cylinders = (device->blocks << device->s2b_shift) >> 10;
461         geo->heads = 16;
462         geo->sectors = 128 >> device->s2b_shift;
463         return 0;
464 }
465
466 static dasd_era_t
467 dasd_diag_examine_error(struct dasd_ccw_req * cqr, struct irb * stat)
468 {
469         return dasd_era_fatal;
470 }
471
472 static dasd_erp_fn_t
473 dasd_diag_erp_action(struct dasd_ccw_req * cqr)
474 {
475         return dasd_default_erp_action;
476 }
477
478 static dasd_erp_fn_t
479 dasd_diag_erp_postaction(struct dasd_ccw_req * cqr)
480 {
481         return dasd_default_erp_postaction;
482 }
483
484 /* Create DASD request from block device request. Return pointer to new
485  * request on success, ERR_PTR otherwise. */
486 static struct dasd_ccw_req *
487 dasd_diag_build_cp(struct dasd_device * device, struct request *req)
488 {
489         struct dasd_ccw_req *cqr;
490         struct dasd_diag_req *dreq;
491         struct dasd_diag_bio *dbio;
492         struct bio *bio;
493         struct bio_vec *bv;
494         char *dst;
495         unsigned int count, datasize;
496         sector_t recid, first_rec, last_rec;
497         unsigned int blksize, off;
498         unsigned char rw_cmd;
499         int i;
500
501         if (rq_data_dir(req) == READ)
502                 rw_cmd = MDSK_READ_REQ;
503         else if (rq_data_dir(req) == WRITE)
504                 rw_cmd = MDSK_WRITE_REQ;
505         else
506                 return ERR_PTR(-EINVAL);
507         blksize = device->bp_block;
508         /* Calculate record id of first and last block. */
509         first_rec = req->sector >> device->s2b_shift;
510         last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift;
511         /* Check struct bio and count the number of blocks for the request. */
512         count = 0;
513         rq_for_each_bio(bio, req) {
514                 bio_for_each_segment(bv, bio, i) {
515                         if (bv->bv_len & (blksize - 1))
516                                 /* Fba can only do full blocks. */
517                                 return ERR_PTR(-EINVAL);
518                         count += bv->bv_len >> (device->s2b_shift + 9);
519                 }
520         }
521         /* Paranoia. */
522         if (count != last_rec - first_rec + 1)
523                 return ERR_PTR(-EINVAL);
524         /* Build the request */
525         datasize = sizeof(struct dasd_diag_req) +
526                 count*sizeof(struct dasd_diag_bio);
527         cqr = dasd_smalloc_request(dasd_diag_discipline.name, 0,
528                                    datasize, device);
529         if (IS_ERR(cqr))
530                 return cqr;
531         
532         dreq = (struct dasd_diag_req *) cqr->data;
533         dreq->block_count = count;
534         dbio = dreq->bio;
535         recid = first_rec;
536         rq_for_each_bio(bio, req) {
537                 bio_for_each_segment(bv, bio, i) {
538                         dst = page_address(bv->bv_page) + bv->bv_offset;
539                         for (off = 0; off < bv->bv_len; off += blksize) {
540                                 memset(dbio, 0, sizeof (struct dasd_diag_bio));
541                                 dbio->type = rw_cmd;
542                                 dbio->block_number = recid + 1;
543                                 dbio->buffer = dst;
544                                 dbio++;
545                                 dst += blksize;
546                                 recid++;
547                         }
548                 }
549         }
550         cqr->retries = DIAG_MAX_RETRIES;
551         cqr->buildclk = get_clock();
552         if (req->flags & REQ_FAILFAST)
553                 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
554         cqr->device = device;
555         cqr->expires = DIAG_TIMEOUT;
556         cqr->status = DASD_CQR_FILLED;
557         return cqr;
558 }
559
560 /* Release DASD request. Return non-zero if request was successful, zero
561  * otherwise. */
562 static int
563 dasd_diag_free_cp(struct dasd_ccw_req *cqr, struct request *req)
564 {
565         int status;
566
567         status = cqr->status == DASD_CQR_DONE;
568         dasd_sfree_request(cqr, cqr->device);
569         return status;
570 }
571
572 /* Fill in IOCTL data for device. */
573 static int
574 dasd_diag_fill_info(struct dasd_device * device,
575                     struct dasd_information2_t * info)
576 {
577         struct dasd_diag_private *private;
578
579         private = (struct dasd_diag_private *) device->private;
580         info->label_block = (unsigned int) private->pt_block;
581         info->FBA_layout = 1;
582         info->format = DASD_FORMAT_LDL;
583         info->characteristics_size = sizeof (struct dasd_diag_characteristics);
584         memcpy(info->characteristics,
585                &((struct dasd_diag_private *) device->private)->rdc_data,
586                sizeof (struct dasd_diag_characteristics));
587         info->confdata_size = 0;
588         return 0;
589 }
590
591 static void
592 dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
593                      struct irb *stat)
594 {
595         DEV_MESSAGE(KERN_ERR, device, "%s",
596                     "dump sense not available for DIAG data");
597 }
598
599 struct dasd_discipline dasd_diag_discipline = {
600         .owner = THIS_MODULE,
601         .name = "DIAG",
602         .ebcname = "DIAG",
603         .max_blocks = DIAG_MAX_BLOCKS,
604         .check_device = dasd_diag_check_device,
605         .fill_geometry = dasd_diag_fill_geometry,
606         .start_IO = dasd_start_diag,
607         .term_IO = dasd_diag_term_IO,
608         .examine_error = dasd_diag_examine_error,
609         .erp_action = dasd_diag_erp_action,
610         .erp_postaction = dasd_diag_erp_postaction,
611         .build_cp = dasd_diag_build_cp,
612         .free_cp = dasd_diag_free_cp,
613         .dump_sense = dasd_diag_dump_sense,
614         .fill_info = dasd_diag_fill_info,
615 };
616
617 static int __init
618 dasd_diag_init(void)
619 {
620         if (!MACHINE_IS_VM) {
621                 MESSAGE_LOG(KERN_INFO,
622                             "Machine is not VM: %s "
623                             "discipline not initializing",
624                             dasd_diag_discipline.name);
625                 return -ENODEV;
626         }
627         ASCEBC(dasd_diag_discipline.ebcname, 4);
628
629         ctl_set_bit(0, 9);
630         register_external_interrupt(0x2603, dasd_ext_handler);
631         dasd_diag_discipline_pointer = &dasd_diag_discipline;
632         return 0;
633 }
634
635 static void __exit
636 dasd_diag_cleanup(void)
637 {
638         unregister_external_interrupt(0x2603, dasd_ext_handler);
639         ctl_clear_bit(0, 9);
640         dasd_diag_discipline_pointer = NULL;
641 }
642
643 module_init(dasd_diag_init);
644 module_exit(dasd_diag_cleanup);