1
2
3
4
5
6
7
8
9
10
11
12
13#define KMSG_COMPONENT "dasd-eckd"
14
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/hdreg.h>
19#include <linux/bio.h>
20#include <linux/module.h>
21#include <linux/compat.h>
22#include <linux/init.h>
23#include <linux/seq_file.h>
24
25#include <asm/css_chars.h>
26#include <asm/debug.h>
27#include <asm/idals.h>
28#include <asm/ebcdic.h>
29#include <asm/io.h>
30#include <linux/uaccess.h>
31#include <asm/cio.h>
32#include <asm/ccwdev.h>
33#include <asm/itcw.h>
34#include <asm/schid.h>
35#include <asm/chpid.h>
36
37#include "dasd_int.h"
38#include "dasd_eckd.h"
39
40#ifdef PRINTK_HEADER
41#undef PRINTK_HEADER
42#endif
43#define PRINTK_HEADER "dasd(eckd):"
44
45
46
47
48
49#define DASD_RAW_BLOCK_PER_TRACK 16
50#define DASD_RAW_BLOCKSIZE 4096
51
52#define DASD_RAW_SECTORS_PER_TRACK 128
53
54MODULE_LICENSE("GPL");
55
56static struct dasd_discipline dasd_eckd_discipline;
57
58
59
60static struct ccw_device_id dasd_eckd_ids[] = {
61 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1},
62 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2},
63 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3380, 0), .driver_info = 0x3},
64 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4},
65 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5},
66 { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6},
67 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3390, 0), .driver_info = 0x7},
68 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3380, 0), .driver_info = 0x8},
69 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3390, 0), .driver_info = 0x9},
70 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3380, 0), .driver_info = 0xa},
71 { },
72};
73
74MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);
75
76static struct ccw_driver dasd_eckd_driver;
77
78static void *rawpadpage;
79
80#define INIT_CQR_OK 0
81#define INIT_CQR_UNFORMATTED 1
82#define INIT_CQR_ERROR 2
83
84
85static struct {
86 struct dasd_ccw_req cqr;
87 struct ccw1 ccw;
88 char data[32];
89} *dasd_reserve_req;
90static DEFINE_MUTEX(dasd_reserve_mutex);
91
92static struct {
93 struct dasd_ccw_req cqr;
94 struct ccw1 ccw[2];
95 char data[40];
96} *dasd_vol_info_req;
97static DEFINE_MUTEX(dasd_vol_info_mutex);
98
99struct ext_pool_exhaust_work_data {
100 struct work_struct worker;
101 struct dasd_device *device;
102 struct dasd_device *base;
103};
104
105
106struct pe_handler_work_data {
107 struct work_struct worker;
108 struct dasd_device *device;
109 struct dasd_ccw_req cqr;
110 struct ccw1 ccw;
111 __u8 rcd_buffer[DASD_ECKD_RCD_DATA_SIZE];
112 int isglobal;
113 __u8 tbvpm;
114 __u8 fcsecpm;
115};
116static struct pe_handler_work_data *pe_handler_worker;
117static DEFINE_MUTEX(dasd_pe_handler_mutex);
118
119struct check_attention_work_data {
120 struct work_struct worker;
121 struct dasd_device *device;
122 __u8 lpum;
123};
124
125static int dasd_eckd_ext_pool_id(struct dasd_device *);
126static int prepare_itcw(struct itcw *, unsigned int, unsigned int, int,
127 struct dasd_device *, struct dasd_device *,
128 unsigned int, int, unsigned int, unsigned int,
129 unsigned int, unsigned int);
130
131
132
133static int
134dasd_eckd_probe (struct ccw_device *cdev)
135{
136 int ret;
137
138
139 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE |
140 CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH);
141 if (ret) {
142 DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
143 "dasd_eckd_probe: could not set "
144 "ccw-device options");
145 return ret;
146 }
147 ret = dasd_generic_probe(cdev);
148 return ret;
149}
150
151static int
152dasd_eckd_set_online(struct ccw_device *cdev)
153{
154 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
155}
156
157static const int sizes_trk0[] = { 28, 148, 84 };
158#define LABEL_SIZE 140
159
160
161static const int count_area_head[] = { 0, 0, 0, 0, 1 };
162static const int count_area_rec[] = { 1, 2, 3, 4, 1 };
163
164static inline unsigned int
165ceil_quot(unsigned int d1, unsigned int d2)
166{
167 return (d1 + (d2 - 1)) / d2;
168}
169
170static unsigned int
171recs_per_track(struct dasd_eckd_characteristics * rdc,
172 unsigned int kl, unsigned int dl)
173{
174 int dn, kn;
175
176 switch (rdc->dev_type) {
177 case 0x3380:
178 if (kl)
179 return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) +
180 ceil_quot(dl + 12, 32));
181 else
182 return 1499 / (15 + ceil_quot(dl + 12, 32));
183 case 0x3390:
184 dn = ceil_quot(dl + 6, 232) + 1;
185 if (kl) {
186 kn = ceil_quot(kl + 6, 232) + 1;
187 return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
188 9 + ceil_quot(dl + 6 * dn, 34));
189 } else
190 return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
191 case 0x9345:
192 dn = ceil_quot(dl + 6, 232) + 1;
193 if (kl) {
194 kn = ceil_quot(kl + 6, 232) + 1;
195 return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) +
196 ceil_quot(dl + 6 * dn, 34));
197 } else
198 return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34));
199 }
200 return 0;
201}
202
203static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
204{
205 geo->cyl = (__u16) cyl;
206 geo->head = cyl >> 16;
207 geo->head <<= 4;
208 geo->head |= head;
209}
210
211
212
213
214
215static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device,
216 sector_t *track)
217{
218 struct dasd_eckd_private *private = device->private;
219 u8 *sense = NULL;
220 u32 cyl;
221 u8 head;
222
223 sense = dasd_get_sense(irb);
224 if (!sense) {
225 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
226 "ESE error no sense data\n");
227 return -EINVAL;
228 }
229 if (!(sense[27] & DASD_SENSE_BIT_2)) {
230 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
231 "ESE error no valid track data\n");
232 return -EINVAL;
233 }
234
235 if (sense[27] & DASD_SENSE_BIT_3) {
236
237 cyl = sense[30] << 20;
238 cyl |= (sense[31] & 0xF0) << 12;
239 cyl |= sense[28] << 8;
240 cyl |= sense[29];
241 } else {
242 cyl = sense[29] << 8;
243 cyl |= sense[30];
244 }
245 head = sense[31] & 0x0F;
246 *track = cyl * private->rdc_data.trk_per_cyl + head;
247 return 0;
248}
249
250static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data,
251 struct dasd_device *device)
252{
253 struct dasd_eckd_private *private = device->private;
254 int rc;
255
256 rc = get_phys_clock(&data->ep_sys_time);
257
258
259
260
261 if ((rc && !private->rdc_data.facilities.XRC_supported) ||
262 rc == -EOPNOTSUPP || rc == -EACCES)
263 return 0;
264
265
266 data->ga_extended |= 0x08;
267 data->ga_extended |= 0x02;
268
269 if (ccw) {
270 ccw->count = sizeof(struct DE_eckd_data);
271 ccw->flags |= CCW_FLAG_SLI;
272 }
273
274 return rc;
275}
276
277static int
278define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
279 unsigned int totrk, int cmd, struct dasd_device *device,
280 int blksize)
281{
282 struct dasd_eckd_private *private = device->private;
283 u16 heads, beghead, endhead;
284 u32 begcyl, endcyl;
285 int rc = 0;
286
287 if (ccw) {
288 ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
289 ccw->flags = 0;
290 ccw->count = 16;
291 ccw->cda = (__u32)__pa(data);
292 }
293
294 memset(data, 0, sizeof(struct DE_eckd_data));
295 switch (cmd) {
296 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
297 case DASD_ECKD_CCW_READ_RECORD_ZERO:
298 case DASD_ECKD_CCW_READ:
299 case DASD_ECKD_CCW_READ_MT:
300 case DASD_ECKD_CCW_READ_CKD:
301 case DASD_ECKD_CCW_READ_CKD_MT:
302 case DASD_ECKD_CCW_READ_KD:
303 case DASD_ECKD_CCW_READ_KD_MT:
304 data->mask.perm = 0x1;
305 data->attributes.operation = private->attrib.operation;
306 break;
307 case DASD_ECKD_CCW_READ_COUNT:
308 data->mask.perm = 0x1;
309 data->attributes.operation = DASD_BYPASS_CACHE;
310 break;
311 case DASD_ECKD_CCW_READ_TRACK:
312 case DASD_ECKD_CCW_READ_TRACK_DATA:
313 data->mask.perm = 0x1;
314 data->attributes.operation = private->attrib.operation;
315 data->blk_size = 0;
316 break;
317 case DASD_ECKD_CCW_WRITE:
318 case DASD_ECKD_CCW_WRITE_MT:
319 case DASD_ECKD_CCW_WRITE_KD:
320 case DASD_ECKD_CCW_WRITE_KD_MT:
321 data->mask.perm = 0x02;
322 data->attributes.operation = private->attrib.operation;
323 rc = set_timestamp(ccw, data, device);
324 break;
325 case DASD_ECKD_CCW_WRITE_CKD:
326 case DASD_ECKD_CCW_WRITE_CKD_MT:
327 data->attributes.operation = DASD_BYPASS_CACHE;
328 rc = set_timestamp(ccw, data, device);
329 break;
330 case DASD_ECKD_CCW_ERASE:
331 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
332 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
333 data->mask.perm = 0x3;
334 data->mask.auth = 0x1;
335 data->attributes.operation = DASD_BYPASS_CACHE;
336 rc = set_timestamp(ccw, data, device);
337 break;
338 case DASD_ECKD_CCW_WRITE_FULL_TRACK:
339 data->mask.perm = 0x03;
340 data->attributes.operation = private->attrib.operation;
341 data->blk_size = 0;
342 break;
343 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
344 data->mask.perm = 0x02;
345 data->attributes.operation = private->attrib.operation;
346 data->blk_size = blksize;
347 rc = set_timestamp(ccw, data, device);
348 break;
349 default:
350 dev_err(&device->cdev->dev,
351 "0x%x is not a known command\n", cmd);
352 break;
353 }
354
355 data->attributes.mode = 0x3;
356
357 if ((private->rdc_data.cu_type == 0x2105 ||
358 private->rdc_data.cu_type == 0x2107 ||
359 private->rdc_data.cu_type == 0x1750)
360 && !(private->uses_cdl && trk < 2))
361 data->ga_extended |= 0x40;
362
363 heads = private->rdc_data.trk_per_cyl;
364 begcyl = trk / heads;
365 beghead = trk % heads;
366 endcyl = totrk / heads;
367 endhead = totrk % heads;
368
369
370 if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
371 data->attributes.operation == DASD_SEQ_ACCESS) {
372
373 if (endcyl + private->attrib.nr_cyl < private->real_cyl)
374 endcyl += private->attrib.nr_cyl;
375 else
376 endcyl = (private->real_cyl - 1);
377 }
378
379 set_ch_t(&data->beg_ext, begcyl, beghead);
380 set_ch_t(&data->end_ext, endcyl, endhead);
381 return rc;
382}
383
384
385static void locate_record_ext(struct ccw1 *ccw, struct LRE_eckd_data *data,
386 unsigned int trk, unsigned int rec_on_trk,
387 int count, int cmd, struct dasd_device *device,
388 unsigned int reclen, unsigned int tlf)
389{
390 struct dasd_eckd_private *private = device->private;
391 int sector;
392 int dn, d;
393
394 if (ccw) {
395 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD_EXT;
396 ccw->flags = 0;
397 if (cmd == DASD_ECKD_CCW_WRITE_FULL_TRACK)
398 ccw->count = 22;
399 else
400 ccw->count = 20;
401 ccw->cda = (__u32)__pa(data);
402 }
403
404 memset(data, 0, sizeof(*data));
405 sector = 0;
406 if (rec_on_trk) {
407 switch (private->rdc_data.dev_type) {
408 case 0x3390:
409 dn = ceil_quot(reclen + 6, 232);
410 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
411 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
412 break;
413 case 0x3380:
414 d = 7 + ceil_quot(reclen + 12, 32);
415 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
416 break;
417 }
418 }
419 data->sector = sector;
420
421
422
423
424 data->count = count;
425 switch (cmd) {
426 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
427 data->operation.orientation = 0x3;
428 data->operation.operation = 0x03;
429 break;
430 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
431 data->operation.orientation = 0x3;
432 data->operation.operation = 0x16;
433 break;
434 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
435 data->operation.orientation = 0x1;
436 data->operation.operation = 0x03;
437 data->count++;
438 break;
439 case DASD_ECKD_CCW_READ_RECORD_ZERO:
440 data->operation.orientation = 0x3;
441 data->operation.operation = 0x16;
442 data->count++;
443 break;
444 case DASD_ECKD_CCW_WRITE:
445 case DASD_ECKD_CCW_WRITE_MT:
446 case DASD_ECKD_CCW_WRITE_KD:
447 case DASD_ECKD_CCW_WRITE_KD_MT:
448 data->auxiliary.length_valid = 0x1;
449 data->length = reclen;
450 data->operation.operation = 0x01;
451 break;
452 case DASD_ECKD_CCW_WRITE_CKD:
453 case DASD_ECKD_CCW_WRITE_CKD_MT:
454 data->auxiliary.length_valid = 0x1;
455 data->length = reclen;
456 data->operation.operation = 0x03;
457 break;
458 case DASD_ECKD_CCW_WRITE_FULL_TRACK:
459 data->operation.orientation = 0x0;
460 data->operation.operation = 0x3F;
461 data->extended_operation = 0x11;
462 data->length = 0;
463 data->extended_parameter_length = 0x02;
464 if (data->count > 8) {
465 data->extended_parameter[0] = 0xFF;
466 data->extended_parameter[1] = 0xFF;
467 data->extended_parameter[1] <<= (16 - count);
468 } else {
469 data->extended_parameter[0] = 0xFF;
470 data->extended_parameter[0] <<= (8 - count);
471 data->extended_parameter[1] = 0x00;
472 }
473 data->sector = 0xFF;
474 break;
475 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
476 data->auxiliary.length_valid = 0x1;
477 data->length = reclen;
478 data->operation.operation = 0x3F;
479 data->extended_operation = 0x23;
480 break;
481 case DASD_ECKD_CCW_READ:
482 case DASD_ECKD_CCW_READ_MT:
483 case DASD_ECKD_CCW_READ_KD:
484 case DASD_ECKD_CCW_READ_KD_MT:
485 data->auxiliary.length_valid = 0x1;
486 data->length = reclen;
487 data->operation.operation = 0x06;
488 break;
489 case DASD_ECKD_CCW_READ_CKD:
490 case DASD_ECKD_CCW_READ_CKD_MT:
491 data->auxiliary.length_valid = 0x1;
492 data->length = reclen;
493 data->operation.operation = 0x16;
494 break;
495 case DASD_ECKD_CCW_READ_COUNT:
496 data->operation.operation = 0x06;
497 break;
498 case DASD_ECKD_CCW_READ_TRACK:
499 data->operation.orientation = 0x1;
500 data->operation.operation = 0x0C;
501 data->extended_parameter_length = 0;
502 data->sector = 0xFF;
503 break;
504 case DASD_ECKD_CCW_READ_TRACK_DATA:
505 data->auxiliary.length_valid = 0x1;
506 data->length = tlf;
507 data->operation.operation = 0x0C;
508 break;
509 case DASD_ECKD_CCW_ERASE:
510 data->length = reclen;
511 data->auxiliary.length_valid = 0x1;
512 data->operation.operation = 0x0b;
513 break;
514 default:
515 DBF_DEV_EVENT(DBF_ERR, device,
516 "fill LRE unknown opcode 0x%x", cmd);
517 BUG();
518 }
519 set_ch_t(&data->seek_addr,
520 trk / private->rdc_data.trk_per_cyl,
521 trk % private->rdc_data.trk_per_cyl);
522 data->search_arg.cyl = data->seek_addr.cyl;
523 data->search_arg.head = data->seek_addr.head;
524 data->search_arg.record = rec_on_trk;
525}
526
527static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
528 unsigned int trk, unsigned int totrk, int cmd,
529 struct dasd_device *basedev, struct dasd_device *startdev,
530 unsigned int format, unsigned int rec_on_trk, int count,
531 unsigned int blksize, unsigned int tlf)
532{
533 struct dasd_eckd_private *basepriv, *startpriv;
534 struct LRE_eckd_data *lredata;
535 struct DE_eckd_data *dedata;
536 int rc = 0;
537
538 basepriv = basedev->private;
539 startpriv = startdev->private;
540 dedata = &pfxdata->define_extent;
541 lredata = &pfxdata->locate_record;
542
543 ccw->cmd_code = DASD_ECKD_CCW_PFX;
544 ccw->flags = 0;
545 if (cmd == DASD_ECKD_CCW_WRITE_FULL_TRACK) {
546 ccw->count = sizeof(*pfxdata) + 2;
547 ccw->cda = (__u32) __pa(pfxdata);
548 memset(pfxdata, 0, sizeof(*pfxdata) + 2);
549 } else {
550 ccw->count = sizeof(*pfxdata);
551 ccw->cda = (__u32) __pa(pfxdata);
552 memset(pfxdata, 0, sizeof(*pfxdata));
553 }
554
555
556 if (format > 1) {
557 DBF_DEV_EVENT(DBF_ERR, basedev,
558 "PFX LRE unknown format 0x%x", format);
559 BUG();
560 return -EINVAL;
561 }
562 pfxdata->format = format;
563 pfxdata->base_address = basepriv->ned->unit_addr;
564 pfxdata->base_lss = basepriv->ned->ID;
565 pfxdata->validity.define_extent = 1;
566
567
568 if (startpriv->uid.type == UA_BASE_PAV_ALIAS)
569 pfxdata->validity.verify_base = 1;
570
571 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS) {
572 pfxdata->validity.verify_base = 1;
573 pfxdata->validity.hyper_pav = 1;
574 }
575
576 rc = define_extent(NULL, dedata, trk, totrk, cmd, basedev, blksize);
577
578
579
580
581
582
583 if (dedata->ga_extended & 0x08 && dedata->ga_extended & 0x02)
584 pfxdata->validity.time_stamp = 1;
585
586 if (format == 1) {
587 locate_record_ext(NULL, lredata, trk, rec_on_trk, count, cmd,
588 basedev, blksize, tlf);
589 }
590
591 return rc;
592}
593
594static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
595 unsigned int trk, unsigned int totrk, int cmd,
596 struct dasd_device *basedev, struct dasd_device *startdev)
597{
598 return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
599 0, 0, 0, 0, 0);
600}
601
602static void
603locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
604 unsigned int rec_on_trk, int no_rec, int cmd,
605 struct dasd_device * device, int reclen)
606{
607 struct dasd_eckd_private *private = device->private;
608 int sector;
609 int dn, d;
610
611 DBF_DEV_EVENT(DBF_INFO, device,
612 "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",
613 trk, rec_on_trk, no_rec, cmd, reclen);
614
615 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
616 ccw->flags = 0;
617 ccw->count = 16;
618 ccw->cda = (__u32) __pa(data);
619
620 memset(data, 0, sizeof(struct LO_eckd_data));
621 sector = 0;
622 if (rec_on_trk) {
623 switch (private->rdc_data.dev_type) {
624 case 0x3390:
625 dn = ceil_quot(reclen + 6, 232);
626 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
627 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
628 break;
629 case 0x3380:
630 d = 7 + ceil_quot(reclen + 12, 32);
631 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
632 break;
633 }
634 }
635 data->sector = sector;
636 data->count = no_rec;
637 switch (cmd) {
638 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
639 data->operation.orientation = 0x3;
640 data->operation.operation = 0x03;
641 break;
642 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
643 data->operation.orientation = 0x3;
644 data->operation.operation = 0x16;
645 break;
646 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
647 data->operation.orientation = 0x1;
648 data->operation.operation = 0x03;
649 data->count++;
650 break;
651 case DASD_ECKD_CCW_READ_RECORD_ZERO:
652 data->operation.orientation = 0x3;
653 data->operation.operation = 0x16;
654 data->count++;
655 break;
656 case DASD_ECKD_CCW_WRITE:
657 case DASD_ECKD_CCW_WRITE_MT:
658 case DASD_ECKD_CCW_WRITE_KD:
659 case DASD_ECKD_CCW_WRITE_KD_MT:
660 data->auxiliary.last_bytes_used = 0x1;
661 data->length = reclen;
662 data->operation.operation = 0x01;
663 break;
664 case DASD_ECKD_CCW_WRITE_CKD:
665 case DASD_ECKD_CCW_WRITE_CKD_MT:
666 data->auxiliary.last_bytes_used = 0x1;
667 data->length = reclen;
668 data->operation.operation = 0x03;
669 break;
670 case DASD_ECKD_CCW_READ:
671 case DASD_ECKD_CCW_READ_MT:
672 case DASD_ECKD_CCW_READ_KD:
673 case DASD_ECKD_CCW_READ_KD_MT:
674 data->auxiliary.last_bytes_used = 0x1;
675 data->length = reclen;
676 data->operation.operation = 0x06;
677 break;
678 case DASD_ECKD_CCW_READ_CKD:
679 case DASD_ECKD_CCW_READ_CKD_MT:
680 data->auxiliary.last_bytes_used = 0x1;
681 data->length = reclen;
682 data->operation.operation = 0x16;
683 break;
684 case DASD_ECKD_CCW_READ_COUNT:
685 data->operation.operation = 0x06;
686 break;
687 case DASD_ECKD_CCW_ERASE:
688 data->length = reclen;
689 data->auxiliary.last_bytes_used = 0x1;
690 data->operation.operation = 0x0b;
691 break;
692 default:
693 DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "
694 "opcode 0x%x", cmd);
695 }
696 set_ch_t(&data->seek_addr,
697 trk / private->rdc_data.trk_per_cyl,
698 trk % private->rdc_data.trk_per_cyl);
699 data->search_arg.cyl = data->seek_addr.cyl;
700 data->search_arg.head = data->seek_addr.head;
701 data->search_arg.record = rec_on_trk;
702}
703
704
705
706
707
708
709
710
711
712
713
714static inline int
715dasd_eckd_cdl_special(int blk_per_trk, int recid)
716{
717 if (recid < 3)
718 return 1;
719 if (recid < blk_per_trk)
720 return 0;
721 if (recid < 2 * blk_per_trk)
722 return 1;
723 return 0;
724}
725
726
727
728
729
730
731static inline int
732dasd_eckd_cdl_reclen(int recid)
733{
734 if (recid < 3)
735 return sizes_trk0[recid];
736 return LABEL_SIZE;
737}
738
739static void create_uid(struct dasd_eckd_private *private)
740{
741 int count;
742 struct dasd_uid *uid;
743
744 uid = &private->uid;
745 memset(uid, 0, sizeof(struct dasd_uid));
746 memcpy(uid->vendor, private->ned->HDA_manufacturer,
747 sizeof(uid->vendor) - 1);
748 EBCASC(uid->vendor, sizeof(uid->vendor) - 1);
749 memcpy(uid->serial, private->ned->HDA_location,
750 sizeof(uid->serial) - 1);
751 EBCASC(uid->serial, sizeof(uid->serial) - 1);
752 uid->ssid = private->gneq->subsystemID;
753 uid->real_unit_addr = private->ned->unit_addr;
754 if (private->sneq) {
755 uid->type = private->sneq->sua_flags;
756 if (uid->type == UA_BASE_PAV_ALIAS)
757 uid->base_unit_addr = private->sneq->base_unit_addr;
758 } else {
759 uid->type = UA_BASE_DEVICE;
760 }
761 if (private->vdsneq) {
762 for (count = 0; count < 16; count++) {
763 sprintf(uid->vduit+2*count, "%02x",
764 private->vdsneq->uit[count]);
765 }
766 }
767}
768
769
770
771
772static int dasd_eckd_generate_uid(struct dasd_device *device)
773{
774 struct dasd_eckd_private *private = device->private;
775 unsigned long flags;
776
777 if (!private)
778 return -ENODEV;
779 if (!private->ned || !private->gneq)
780 return -ENODEV;
781 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
782 create_uid(private);
783 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
784 return 0;
785}
786
787static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)
788{
789 struct dasd_eckd_private *private = device->private;
790 unsigned long flags;
791
792 if (private) {
793 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
794 *uid = private->uid;
795 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
796 return 0;
797 }
798 return -EINVAL;
799}
800
801
802
803
804
805static int dasd_eckd_compare_path_uid(struct dasd_device *device,
806 struct dasd_eckd_private *private)
807{
808 struct dasd_uid device_uid;
809
810 create_uid(private);
811 dasd_eckd_get_uid(device, &device_uid);
812
813 return memcmp(&device_uid, &private->uid, sizeof(struct dasd_uid));
814}
815
816static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
817 struct dasd_ccw_req *cqr,
818 __u8 *rcd_buffer,
819 __u8 lpm)
820{
821 struct ccw1 *ccw;
822
823
824
825
826 rcd_buffer[0] = 0xE5;
827 rcd_buffer[1] = 0xF1;
828 rcd_buffer[2] = 0x4B;
829 rcd_buffer[3] = 0xF0;
830
831 ccw = cqr->cpaddr;
832 ccw->cmd_code = DASD_ECKD_CCW_RCD;
833 ccw->flags = 0;
834 ccw->cda = (__u32)(addr_t)rcd_buffer;
835 ccw->count = DASD_ECKD_RCD_DATA_SIZE;
836 cqr->magic = DASD_ECKD_MAGIC;
837
838 cqr->startdev = device;
839 cqr->memdev = device;
840 cqr->block = NULL;
841 cqr->expires = 10*HZ;
842 cqr->lpm = lpm;
843 cqr->retries = 256;
844 cqr->buildclk = get_tod_clock();
845 cqr->status = DASD_CQR_FILLED;
846 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
847}
848
849
850
851
852
853
854
855static void read_conf_cb(struct dasd_ccw_req *cqr, void *data)
856{
857 struct ccw1 *ccw;
858 __u8 *rcd_buffer;
859
860 if (cqr->status != DASD_CQR_DONE) {
861 ccw = cqr->cpaddr;
862 rcd_buffer = (__u8 *)((addr_t) ccw->cda);
863 memset(rcd_buffer, 0, sizeof(*rcd_buffer));
864
865 rcd_buffer[0] = 0xE5;
866 rcd_buffer[1] = 0xF1;
867 rcd_buffer[2] = 0x4B;
868 rcd_buffer[3] = 0xF0;
869 }
870 dasd_wakeup_cb(cqr, data);
871}
872
873static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
874 struct dasd_ccw_req *cqr,
875 __u8 *rcd_buffer,
876 __u8 lpm)
877{
878 struct ciw *ciw;
879 int rc;
880
881
882
883
884 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
885 if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD)
886 return -EOPNOTSUPP;
887
888 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buffer, lpm);
889 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
890 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
891 cqr->retries = 5;
892 cqr->callback = read_conf_cb;
893 rc = dasd_sleep_on_immediatly(cqr);
894 return rc;
895}
896
897static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
898 void **rcd_buffer,
899 int *rcd_buffer_size, __u8 lpm)
900{
901 struct ciw *ciw;
902 char *rcd_buf = NULL;
903 int ret;
904 struct dasd_ccw_req *cqr;
905
906
907
908
909
910 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
911 if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD) {
912 ret = -EOPNOTSUPP;
913 goto out_error;
914 }
915 rcd_buf = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL | GFP_DMA);
916 if (!rcd_buf) {
917 ret = -ENOMEM;
918 goto out_error;
919 }
920 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 ,
921 0,
922 device, NULL);
923 if (IS_ERR(cqr)) {
924 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
925 "Could not allocate RCD request");
926 ret = -ENOMEM;
927 goto out_error;
928 }
929 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);
930 cqr->callback = read_conf_cb;
931 ret = dasd_sleep_on(cqr);
932
933
934
935 dasd_sfree_request(cqr, cqr->memdev);
936 if (ret)
937 goto out_error;
938
939 *rcd_buffer_size = DASD_ECKD_RCD_DATA_SIZE;
940 *rcd_buffer = rcd_buf;
941 return 0;
942out_error:
943 kfree(rcd_buf);
944 *rcd_buffer = NULL;
945 *rcd_buffer_size = 0;
946 return ret;
947}
948
949static int dasd_eckd_identify_conf_parts(struct dasd_eckd_private *private)
950{
951
952 struct dasd_sneq *sneq;
953 int i, count;
954
955 private->ned = NULL;
956 private->sneq = NULL;
957 private->vdsneq = NULL;
958 private->gneq = NULL;
959 count = private->conf_len / sizeof(struct dasd_sneq);
960 sneq = (struct dasd_sneq *)private->conf_data;
961 for (i = 0; i < count; ++i) {
962 if (sneq->flags.identifier == 1 && sneq->format == 1)
963 private->sneq = sneq;
964 else if (sneq->flags.identifier == 1 && sneq->format == 4)
965 private->vdsneq = (struct vd_sneq *)sneq;
966 else if (sneq->flags.identifier == 2)
967 private->gneq = (struct dasd_gneq *)sneq;
968 else if (sneq->flags.identifier == 3 && sneq->res1 == 1)
969 private->ned = (struct dasd_ned *)sneq;
970 sneq++;
971 }
972 if (!private->ned || !private->gneq) {
973 private->ned = NULL;
974 private->sneq = NULL;
975 private->vdsneq = NULL;
976 private->gneq = NULL;
977 return -EINVAL;
978 }
979 return 0;
980
981};
982
983static unsigned char dasd_eckd_path_access(void *conf_data, int conf_len)
984{
985 struct dasd_gneq *gneq;
986 int i, count, found;
987
988 count = conf_len / sizeof(*gneq);
989 gneq = (struct dasd_gneq *)conf_data;
990 found = 0;
991 for (i = 0; i < count; ++i) {
992 if (gneq->flags.identifier == 2) {
993 found = 1;
994 break;
995 }
996 gneq++;
997 }
998 if (found)
999 return ((char *)gneq)[18] & 0x07;
1000 else
1001 return 0;
1002}
1003
1004static void dasd_eckd_store_conf_data(struct dasd_device *device,
1005 struct dasd_conf_data *conf_data, int chp)
1006{
1007 struct dasd_eckd_private *private = device->private;
1008 struct channel_path_desc_fmt0 *chp_desc;
1009 struct subchannel_id sch_id;
1010 void *cdp;
1011
1012
1013
1014
1015
1016
1017
1018 cdp = device->path[chp].conf_data;
1019 if (private->conf_data == cdp) {
1020 private->conf_data = (void *)conf_data;
1021 dasd_eckd_identify_conf_parts(private);
1022 }
1023 ccw_device_get_schid(device->cdev, &sch_id);
1024 device->path[chp].conf_data = conf_data;
1025 device->path[chp].cssid = sch_id.cssid;
1026 device->path[chp].ssid = sch_id.ssid;
1027 chp_desc = ccw_device_get_chp_desc(device->cdev, chp);
1028 if (chp_desc)
1029 device->path[chp].chpid = chp_desc->chpid;
1030 kfree(chp_desc);
1031 kfree(cdp);
1032}
1033
1034static void dasd_eckd_clear_conf_data(struct dasd_device *device)
1035{
1036 struct dasd_eckd_private *private = device->private;
1037 int i;
1038
1039 private->conf_data = NULL;
1040 private->conf_len = 0;
1041 for (i = 0; i < 8; i++) {
1042 kfree(device->path[i].conf_data);
1043 device->path[i].conf_data = NULL;
1044 device->path[i].cssid = 0;
1045 device->path[i].ssid = 0;
1046 device->path[i].chpid = 0;
1047 dasd_path_notoper(device, i);
1048 }
1049}
1050
1051static void dasd_eckd_read_fc_security(struct dasd_device *device)
1052{
1053 struct dasd_eckd_private *private = device->private;
1054 u8 esm_valid;
1055 u8 esm[8];
1056 int chp;
1057 int rc;
1058
1059 rc = chsc_scud(private->uid.ssid, (u64 *)esm, &esm_valid);
1060 if (rc) {
1061 for (chp = 0; chp < 8; chp++)
1062 device->path[chp].fc_security = 0;
1063 return;
1064 }
1065
1066 for (chp = 0; chp < 8; chp++) {
1067 if (esm_valid & (0x80 >> chp))
1068 device->path[chp].fc_security = esm[chp];
1069 else
1070 device->path[chp].fc_security = 0;
1071 }
1072}
1073
1074static int dasd_eckd_read_conf(struct dasd_device *device)
1075{
1076 void *conf_data;
1077 int conf_len, conf_data_saved;
1078 int rc, path_err, pos;
1079 __u8 lpm, opm;
1080 struct dasd_eckd_private *private, path_private;
1081 struct dasd_uid *uid;
1082 char print_path_uid[60], print_device_uid[60];
1083
1084 private = device->private;
1085 opm = ccw_device_get_path_mask(device->cdev);
1086 conf_data_saved = 0;
1087 path_err = 0;
1088
1089 for (lpm = 0x80; lpm; lpm>>= 1) {
1090 if (!(lpm & opm))
1091 continue;
1092 rc = dasd_eckd_read_conf_lpm(device, &conf_data,
1093 &conf_len, lpm);
1094 if (rc && rc != -EOPNOTSUPP) {
1095 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
1096 "Read configuration data returned "
1097 "error %d", rc);
1098 return rc;
1099 }
1100 if (conf_data == NULL) {
1101 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1102 "No configuration data "
1103 "retrieved");
1104
1105 dasd_path_add_opm(device, opm);
1106 continue;
1107 }
1108
1109 if (!conf_data_saved) {
1110
1111 dasd_eckd_clear_conf_data(device);
1112 private->conf_data = conf_data;
1113 private->conf_len = conf_len;
1114 if (dasd_eckd_identify_conf_parts(private)) {
1115 private->conf_data = NULL;
1116 private->conf_len = 0;
1117 kfree(conf_data);
1118 continue;
1119 }
1120
1121
1122
1123
1124 dasd_eckd_generate_uid(device);
1125 conf_data_saved++;
1126 } else {
1127 path_private.conf_data = conf_data;
1128 path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE;
1129 if (dasd_eckd_identify_conf_parts(
1130 &path_private)) {
1131 path_private.conf_data = NULL;
1132 path_private.conf_len = 0;
1133 kfree(conf_data);
1134 continue;
1135 }
1136 if (dasd_eckd_compare_path_uid(
1137 device, &path_private)) {
1138 uid = &path_private.uid;
1139 if (strlen(uid->vduit) > 0)
1140 snprintf(print_path_uid,
1141 sizeof(print_path_uid),
1142 "%s.%s.%04x.%02x.%s",
1143 uid->vendor, uid->serial,
1144 uid->ssid, uid->real_unit_addr,
1145 uid->vduit);
1146 else
1147 snprintf(print_path_uid,
1148 sizeof(print_path_uid),
1149 "%s.%s.%04x.%02x",
1150 uid->vendor, uid->serial,
1151 uid->ssid,
1152 uid->real_unit_addr);
1153 uid = &private->uid;
1154 if (strlen(uid->vduit) > 0)
1155 snprintf(print_device_uid,
1156 sizeof(print_device_uid),
1157 "%s.%s.%04x.%02x.%s",
1158 uid->vendor, uid->serial,
1159 uid->ssid, uid->real_unit_addr,
1160 uid->vduit);
1161 else
1162 snprintf(print_device_uid,
1163 sizeof(print_device_uid),
1164 "%s.%s.%04x.%02x",
1165 uid->vendor, uid->serial,
1166 uid->ssid,
1167 uid->real_unit_addr);
1168 dev_err(&device->cdev->dev,
1169 "Not all channel paths lead to "
1170 "the same device, path %02X leads to "
1171 "device %s instead of %s\n", lpm,
1172 print_path_uid, print_device_uid);
1173 path_err = -EINVAL;
1174 dasd_path_add_cablepm(device, lpm);
1175 continue;
1176 }
1177 path_private.conf_data = NULL;
1178 path_private.conf_len = 0;
1179 }
1180
1181 pos = pathmask_to_pos(lpm);
1182 dasd_eckd_store_conf_data(device, conf_data, pos);
1183
1184 switch (dasd_eckd_path_access(conf_data, conf_len)) {
1185 case 0x02:
1186 dasd_path_add_nppm(device, lpm);
1187 break;
1188 case 0x03:
1189 dasd_path_add_ppm(device, lpm);
1190 break;
1191 }
1192 if (!dasd_path_get_opm(device)) {
1193 dasd_path_set_opm(device, lpm);
1194 dasd_generic_path_operational(device);
1195 } else {
1196 dasd_path_add_opm(device, lpm);
1197 }
1198 }
1199
1200 dasd_eckd_read_fc_security(device);
1201
1202 return path_err;
1203}
1204
1205static u32 get_fcx_max_data(struct dasd_device *device)
1206{
1207 struct dasd_eckd_private *private = device->private;
1208 int fcx_in_css, fcx_in_gneq, fcx_in_features;
1209 unsigned int mdc;
1210 int tpm;
1211
1212 if (dasd_nofcx)
1213 return 0;
1214
1215 fcx_in_css = css_general_characteristics.fcx;
1216 fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
1217 fcx_in_features = private->features.feature[40] & 0x80;
1218 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
1219
1220 if (!tpm)
1221 return 0;
1222
1223 mdc = ccw_device_get_mdc(device->cdev, 0);
1224 if (mdc == 0) {
1225 dev_warn(&device->cdev->dev, "Detecting the maximum supported data size for zHPF requests failed\n");
1226 return 0;
1227 } else {
1228 return (u32)mdc * FCX_MAX_DATA_FACTOR;
1229 }
1230}
1231
1232static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
1233{
1234 struct dasd_eckd_private *private = device->private;
1235 unsigned int mdc;
1236 u32 fcx_max_data;
1237
1238 if (private->fcx_max_data) {
1239 mdc = ccw_device_get_mdc(device->cdev, lpm);
1240 if (mdc == 0) {
1241 dev_warn(&device->cdev->dev,
1242 "Detecting the maximum data size for zHPF "
1243 "requests failed (rc=%d) for a new path %x\n",
1244 mdc, lpm);
1245 return mdc;
1246 }
1247 fcx_max_data = (u32)mdc * FCX_MAX_DATA_FACTOR;
1248 if (fcx_max_data < private->fcx_max_data) {
1249 dev_warn(&device->cdev->dev,
1250 "The maximum data size for zHPF requests %u "
1251 "on a new path %x is below the active maximum "
1252 "%u\n", fcx_max_data, lpm,
1253 private->fcx_max_data);
1254 return -EACCES;
1255 }
1256 }
1257 return 0;
1258}
1259
1260static int rebuild_device_uid(struct dasd_device *device,
1261 struct pe_handler_work_data *data)
1262{
1263 struct dasd_eckd_private *private = device->private;
1264 __u8 lpm, opm = dasd_path_get_opm(device);
1265 int rc = -ENODEV;
1266
1267 for (lpm = 0x80; lpm; lpm >>= 1) {
1268 if (!(lpm & opm))
1269 continue;
1270 memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer));
1271 memset(&data->cqr, 0, sizeof(data->cqr));
1272 data->cqr.cpaddr = &data->ccw;
1273 rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
1274 data->rcd_buffer,
1275 lpm);
1276
1277 if (rc) {
1278 if (rc == -EOPNOTSUPP)
1279 continue;
1280 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
1281 "Read configuration data "
1282 "returned error %d", rc);
1283 break;
1284 }
1285 memcpy(private->conf_data, data->rcd_buffer,
1286 DASD_ECKD_RCD_DATA_SIZE);
1287 if (dasd_eckd_identify_conf_parts(private)) {
1288 rc = -ENODEV;
1289 } else
1290 break;
1291 }
1292
1293 if (!rc)
1294 rc = dasd_eckd_generate_uid(device);
1295
1296 return rc;
1297}
1298
1299static void dasd_eckd_path_available_action(struct dasd_device *device,
1300 struct pe_handler_work_data *data)
1301{
1302 struct dasd_eckd_private path_private;
1303 struct dasd_uid *uid;
1304 __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE];
1305 __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm;
1306 struct dasd_conf_data *conf_data;
1307 unsigned long flags;
1308 char print_uid[60];
1309 int rc, pos;
1310
1311 opm = 0;
1312 npm = 0;
1313 ppm = 0;
1314 epm = 0;
1315 hpfpm = 0;
1316 cablepm = 0;
1317
1318 for (lpm = 0x80; lpm; lpm >>= 1) {
1319 if (!(lpm & data->tbvpm))
1320 continue;
1321 memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer));
1322 memset(&data->cqr, 0, sizeof(data->cqr));
1323 data->cqr.cpaddr = &data->ccw;
1324 rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
1325 data->rcd_buffer,
1326 lpm);
1327 if (!rc) {
1328 switch (dasd_eckd_path_access(data->rcd_buffer,
1329 DASD_ECKD_RCD_DATA_SIZE)
1330 ) {
1331 case 0x02:
1332 npm |= lpm;
1333 break;
1334 case 0x03:
1335 ppm |= lpm;
1336 break;
1337 }
1338 opm |= lpm;
1339 } else if (rc == -EOPNOTSUPP) {
1340 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1341 "path verification: No configuration "
1342 "data retrieved");
1343 opm |= lpm;
1344 } else if (rc == -EAGAIN) {
1345 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1346 "path verification: device is stopped,"
1347 " try again later");
1348 epm |= lpm;
1349 } else {
1350 dev_warn(&device->cdev->dev,
1351 "Reading device feature codes failed "
1352 "(rc=%d) for new path %x\n", rc, lpm);
1353 continue;
1354 }
1355 if (verify_fcx_max_data(device, lpm)) {
1356 opm &= ~lpm;
1357 npm &= ~lpm;
1358 ppm &= ~lpm;
1359 hpfpm |= lpm;
1360 continue;
1361 }
1362
1363
1364
1365
1366
1367
1368 memcpy(&path_rcd_buf, data->rcd_buffer,
1369 DASD_ECKD_RCD_DATA_SIZE);
1370 path_private.conf_data = (void *) &path_rcd_buf;
1371 path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE;
1372 if (dasd_eckd_identify_conf_parts(&path_private)) {
1373 path_private.conf_data = NULL;
1374 path_private.conf_len = 0;
1375 continue;
1376 }
1377
1378
1379
1380
1381
1382
1383
1384 if (dasd_path_get_opm(device) &&
1385 dasd_eckd_compare_path_uid(device, &path_private)) {
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397 if (rebuild_device_uid(device, data) ||
1398 dasd_eckd_compare_path_uid(
1399 device, &path_private)) {
1400 uid = &path_private.uid;
1401 if (strlen(uid->vduit) > 0)
1402 snprintf(print_uid, sizeof(print_uid),
1403 "%s.%s.%04x.%02x.%s",
1404 uid->vendor, uid->serial,
1405 uid->ssid, uid->real_unit_addr,
1406 uid->vduit);
1407 else
1408 snprintf(print_uid, sizeof(print_uid),
1409 "%s.%s.%04x.%02x",
1410 uid->vendor, uid->serial,
1411 uid->ssid,
1412 uid->real_unit_addr);
1413 dev_err(&device->cdev->dev,
1414 "The newly added channel path %02X "
1415 "will not be used because it leads "
1416 "to a different device %s\n",
1417 lpm, print_uid);
1418 opm &= ~lpm;
1419 npm &= ~lpm;
1420 ppm &= ~lpm;
1421 cablepm |= lpm;
1422 continue;
1423 }
1424 }
1425
1426 conf_data = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL);
1427 if (conf_data) {
1428 memcpy(conf_data, data->rcd_buffer,
1429 DASD_ECKD_RCD_DATA_SIZE);
1430 }
1431 pos = pathmask_to_pos(lpm);
1432 dasd_eckd_store_conf_data(device, conf_data, pos);
1433
1434
1435
1436
1437
1438
1439
1440
1441 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
1442 if (!dasd_path_get_opm(device) && opm) {
1443 dasd_path_set_opm(device, opm);
1444 dasd_generic_path_operational(device);
1445 } else {
1446 dasd_path_add_opm(device, opm);
1447 }
1448 dasd_path_add_nppm(device, npm);
1449 dasd_path_add_ppm(device, ppm);
1450 dasd_path_add_tbvpm(device, epm);
1451 dasd_path_add_cablepm(device, cablepm);
1452 dasd_path_add_nohpfpm(device, hpfpm);
1453 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
1454
1455 dasd_path_create_kobj(device, pos);
1456 }
1457}
1458
1459static void do_pe_handler_work(struct work_struct *work)
1460{
1461 struct pe_handler_work_data *data;
1462 struct dasd_device *device;
1463
1464 data = container_of(work, struct pe_handler_work_data, worker);
1465 device = data->device;
1466
1467
1468 if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
1469 schedule_work(work);
1470 return;
1471 }
1472
1473 if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) {
1474 schedule_work(work);
1475 return;
1476 }
1477
1478 if (data->tbvpm)
1479 dasd_eckd_path_available_action(device, data);
1480 if (data->fcsecpm)
1481 dasd_eckd_read_fc_security(device);
1482
1483 clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags);
1484 dasd_put_device(device);
1485 if (data->isglobal)
1486 mutex_unlock(&dasd_pe_handler_mutex);
1487 else
1488 kfree(data);
1489}
1490
1491static int dasd_eckd_pe_handler(struct dasd_device *device,
1492 __u8 tbvpm, __u8 fcsecpm)
1493{
1494 struct pe_handler_work_data *data;
1495
1496 data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA);
1497 if (!data) {
1498 if (mutex_trylock(&dasd_pe_handler_mutex)) {
1499 data = pe_handler_worker;
1500 data->isglobal = 1;
1501 } else {
1502 return -ENOMEM;
1503 }
1504 } else {
1505 memset(data, 0, sizeof(*data));
1506 data->isglobal = 0;
1507 }
1508 INIT_WORK(&data->worker, do_pe_handler_work);
1509 dasd_get_device(device);
1510 data->device = device;
1511 data->tbvpm = tbvpm;
1512 data->fcsecpm = fcsecpm;
1513 schedule_work(&data->worker);
1514 return 0;
1515}
1516
1517static void dasd_eckd_reset_path(struct dasd_device *device, __u8 pm)
1518{
1519 struct dasd_eckd_private *private = device->private;
1520 unsigned long flags;
1521
1522 if (!private->fcx_max_data)
1523 private->fcx_max_data = get_fcx_max_data(device);
1524 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
1525 dasd_path_set_tbvpm(device, pm ? : dasd_path_get_notoperpm(device));
1526 dasd_schedule_device_bh(device);
1527 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
1528}
1529
1530static int dasd_eckd_read_features(struct dasd_device *device)
1531{
1532 struct dasd_eckd_private *private = device->private;
1533 struct dasd_psf_prssd_data *prssdp;
1534 struct dasd_rssd_features *features;
1535 struct dasd_ccw_req *cqr;
1536 struct ccw1 *ccw;
1537 int rc;
1538
1539 memset(&private->features, 0, sizeof(struct dasd_rssd_features));
1540 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 + 1 ,
1541 (sizeof(struct dasd_psf_prssd_data) +
1542 sizeof(struct dasd_rssd_features)),
1543 device, NULL);
1544 if (IS_ERR(cqr)) {
1545 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not "
1546 "allocate initialization request");
1547 return PTR_ERR(cqr);
1548 }
1549 cqr->startdev = device;
1550 cqr->memdev = device;
1551 cqr->block = NULL;
1552 cqr->retries = 256;
1553 cqr->expires = 10 * HZ;
1554
1555
1556 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
1557 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
1558 prssdp->order = PSF_ORDER_PRSSD;
1559 prssdp->suborder = 0x41;
1560
1561
1562 ccw = cqr->cpaddr;
1563 ccw->cmd_code = DASD_ECKD_CCW_PSF;
1564 ccw->count = sizeof(struct dasd_psf_prssd_data);
1565 ccw->flags |= CCW_FLAG_CC;
1566 ccw->cda = (__u32)(addr_t) prssdp;
1567
1568
1569 features = (struct dasd_rssd_features *) (prssdp + 1);
1570 memset(features, 0, sizeof(struct dasd_rssd_features));
1571
1572 ccw++;
1573 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
1574 ccw->count = sizeof(struct dasd_rssd_features);
1575 ccw->cda = (__u32)(addr_t) features;
1576
1577 cqr->buildclk = get_tod_clock();
1578 cqr->status = DASD_CQR_FILLED;
1579 rc = dasd_sleep_on(cqr);
1580 if (rc == 0) {
1581 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
1582 features = (struct dasd_rssd_features *) (prssdp + 1);
1583 memcpy(&private->features, features,
1584 sizeof(struct dasd_rssd_features));
1585 } else
1586 dev_warn(&device->cdev->dev, "Reading device feature codes"
1587 " failed with rc=%d\n", rc);
1588 dasd_sfree_request(cqr, cqr->memdev);
1589 return rc;
1590}
1591
1592
1593static int dasd_eckd_read_vol_info(struct dasd_device *device)
1594{
1595 struct dasd_eckd_private *private = device->private;
1596 struct dasd_psf_prssd_data *prssdp;
1597 struct dasd_rssd_vsq *vsq;
1598 struct dasd_ccw_req *cqr;
1599 struct ccw1 *ccw;
1600 int useglobal;
1601 int rc;
1602
1603
1604 if (private->uid.type == UA_BASE_PAV_ALIAS ||
1605 private->uid.type == UA_HYPER_PAV_ALIAS)
1606 return 0;
1607
1608 useglobal = 0;
1609 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 ,
1610 sizeof(*prssdp) + sizeof(*vsq), device, NULL);
1611 if (IS_ERR(cqr)) {
1612 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1613 "Could not allocate initialization request");
1614 mutex_lock(&dasd_vol_info_mutex);
1615 useglobal = 1;
1616 cqr = &dasd_vol_info_req->cqr;
1617 memset(cqr, 0, sizeof(*cqr));
1618 memset(dasd_vol_info_req, 0, sizeof(*dasd_vol_info_req));
1619 cqr->cpaddr = &dasd_vol_info_req->ccw;
1620 cqr->data = &dasd_vol_info_req->data;
1621 cqr->magic = DASD_ECKD_MAGIC;
1622 }
1623
1624
1625 prssdp = cqr->data;
1626 prssdp->order = PSF_ORDER_PRSSD;
1627 prssdp->suborder = PSF_SUBORDER_VSQ;
1628 prssdp->lss = private->ned->ID;
1629 prssdp->volume = private->ned->unit_addr;
1630
1631 ccw = cqr->cpaddr;
1632 ccw->cmd_code = DASD_ECKD_CCW_PSF;
1633 ccw->count = sizeof(*prssdp);
1634 ccw->flags |= CCW_FLAG_CC;
1635 ccw->cda = (__u32)(addr_t)prssdp;
1636
1637
1638 vsq = (struct dasd_rssd_vsq *)(prssdp + 1);
1639 memset(vsq, 0, sizeof(*vsq));
1640
1641 ccw++;
1642 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
1643 ccw->count = sizeof(*vsq);
1644 ccw->flags |= CCW_FLAG_SLI;
1645 ccw->cda = (__u32)(addr_t)vsq;
1646
1647 cqr->buildclk = get_tod_clock();
1648 cqr->status = DASD_CQR_FILLED;
1649 cqr->startdev = device;
1650 cqr->memdev = device;
1651 cqr->block = NULL;
1652 cqr->retries = 256;
1653 cqr->expires = device->default_expires * HZ;
1654
1655 __set_bit(DASD_CQR_SUPPRESS_CR, &cqr->flags);
1656
1657 rc = dasd_sleep_on_interruptible(cqr);
1658 if (rc == 0) {
1659 memcpy(&private->vsq, vsq, sizeof(*vsq));
1660 } else {
1661 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
1662 "Reading the volume storage information failed with rc=%d", rc);
1663 }
1664
1665 if (useglobal)
1666 mutex_unlock(&dasd_vol_info_mutex);
1667 else
1668 dasd_sfree_request(cqr, cqr->memdev);
1669
1670 return rc;
1671}
1672
1673static int dasd_eckd_is_ese(struct dasd_device *device)
1674{
1675 struct dasd_eckd_private *private = device->private;
1676
1677 return private->vsq.vol_info.ese;
1678}
1679
1680static int dasd_eckd_ext_pool_id(struct dasd_device *device)
1681{
1682 struct dasd_eckd_private *private = device->private;
1683
1684 return private->vsq.extent_pool_id;
1685}
1686
1687
1688
1689
1690
1691
1692static int dasd_eckd_space_configured(struct dasd_device *device)
1693{
1694 struct dasd_eckd_private *private = device->private;
1695 int rc;
1696
1697 rc = dasd_eckd_read_vol_info(device);
1698
1699 return rc ? : private->vsq.space_configured;
1700}
1701
1702
1703
1704
1705
1706static int dasd_eckd_space_allocated(struct dasd_device *device)
1707{
1708 struct dasd_eckd_private *private = device->private;
1709 int rc;
1710
1711 rc = dasd_eckd_read_vol_info(device);
1712
1713 return rc ? : private->vsq.space_allocated;
1714}
1715
1716static int dasd_eckd_logical_capacity(struct dasd_device *device)
1717{
1718 struct dasd_eckd_private *private = device->private;
1719
1720 return private->vsq.logical_capacity;
1721}
1722
1723static void dasd_eckd_ext_pool_exhaust_work(struct work_struct *work)
1724{
1725 struct ext_pool_exhaust_work_data *data;
1726 struct dasd_device *device;
1727 struct dasd_device *base;
1728
1729 data = container_of(work, struct ext_pool_exhaust_work_data, worker);
1730 device = data->device;
1731 base = data->base;
1732
1733 if (!base)
1734 base = device;
1735 if (dasd_eckd_space_configured(base) != 0) {
1736 dasd_generic_space_avail(device);
1737 } else {
1738 dev_warn(&device->cdev->dev, "No space left in the extent pool\n");
1739 DBF_DEV_EVENT(DBF_WARNING, device, "%s", "out of space");
1740 }
1741
1742 dasd_put_device(device);
1743 kfree(data);
1744}
1745
1746static int dasd_eckd_ext_pool_exhaust(struct dasd_device *device,
1747 struct dasd_ccw_req *cqr)
1748{
1749 struct ext_pool_exhaust_work_data *data;
1750
1751 data = kzalloc(sizeof(*data), GFP_ATOMIC);
1752 if (!data)
1753 return -ENOMEM;
1754 INIT_WORK(&data->worker, dasd_eckd_ext_pool_exhaust_work);
1755 dasd_get_device(device);
1756 data->device = device;
1757
1758 if (cqr->block)
1759 data->base = cqr->block->base;
1760 else if (cqr->basedev)
1761 data->base = cqr->basedev;
1762 else
1763 data->base = NULL;
1764
1765 schedule_work(&data->worker);
1766
1767 return 0;
1768}
1769
1770static void dasd_eckd_cpy_ext_pool_data(struct dasd_device *device,
1771 struct dasd_rssd_lcq *lcq)
1772{
1773 struct dasd_eckd_private *private = device->private;
1774 int pool_id = dasd_eckd_ext_pool_id(device);
1775 struct dasd_ext_pool_sum eps;
1776 int i;
1777
1778 for (i = 0; i < lcq->pool_count; i++) {
1779 eps = lcq->ext_pool_sum[i];
1780 if (eps.pool_id == pool_id) {
1781 memcpy(&private->eps, &eps,
1782 sizeof(struct dasd_ext_pool_sum));
1783 }
1784 }
1785}
1786
1787
1788static int dasd_eckd_read_ext_pool_info(struct dasd_device *device)
1789{
1790 struct dasd_eckd_private *private = device->private;
1791 struct dasd_psf_prssd_data *prssdp;
1792 struct dasd_rssd_lcq *lcq;
1793 struct dasd_ccw_req *cqr;
1794 struct ccw1 *ccw;
1795 int rc;
1796
1797
1798 if (private->uid.type == UA_BASE_PAV_ALIAS ||
1799 private->uid.type == UA_HYPER_PAV_ALIAS)
1800 return 0;
1801
1802 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 ,
1803 sizeof(*prssdp) + sizeof(*lcq), device, NULL);
1804 if (IS_ERR(cqr)) {
1805 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1806 "Could not allocate initialization request");
1807 return PTR_ERR(cqr);
1808 }
1809
1810
1811 prssdp = cqr->data;
1812 memset(prssdp, 0, sizeof(*prssdp));
1813 prssdp->order = PSF_ORDER_PRSSD;
1814 prssdp->suborder = PSF_SUBORDER_LCQ;
1815
1816 ccw = cqr->cpaddr;
1817 ccw->cmd_code = DASD_ECKD_CCW_PSF;
1818 ccw->count = sizeof(*prssdp);
1819 ccw->flags |= CCW_FLAG_CC;
1820 ccw->cda = (__u32)(addr_t)prssdp;
1821
1822 lcq = (struct dasd_rssd_lcq *)(prssdp + 1);
1823 memset(lcq, 0, sizeof(*lcq));
1824
1825 ccw++;
1826 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
1827 ccw->count = sizeof(*lcq);
1828 ccw->flags |= CCW_FLAG_SLI;
1829 ccw->cda = (__u32)(addr_t)lcq;
1830
1831 cqr->buildclk = get_tod_clock();
1832 cqr->status = DASD_CQR_FILLED;
1833 cqr->startdev = device;
1834 cqr->memdev = device;
1835 cqr->block = NULL;
1836 cqr->retries = 256;
1837 cqr->expires = device->default_expires * HZ;
1838
1839 __set_bit(DASD_CQR_SUPPRESS_CR, &cqr->flags);
1840
1841 rc = dasd_sleep_on_interruptible(cqr);
1842 if (rc == 0) {
1843 dasd_eckd_cpy_ext_pool_data(device, lcq);
1844 } else {
1845 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
1846 "Reading the logical configuration failed with rc=%d", rc);
1847 }
1848
1849 dasd_sfree_request(cqr, cqr->memdev);
1850
1851 return rc;
1852}
1853
1854
1855
1856
1857
1858
1859static int dasd_eckd_ext_size(struct dasd_device *device)
1860{
1861 struct dasd_eckd_private *private = device->private;
1862 struct dasd_ext_pool_sum eps = private->eps;
1863
1864 if (!eps.flags.extent_size_valid)
1865 return 0;
1866 if (eps.extent_size.size_1G)
1867 return 1113;
1868 if (eps.extent_size.size_16M)
1869 return 21;
1870
1871 return 0;
1872}
1873
1874static int dasd_eckd_ext_pool_warn_thrshld(struct dasd_device *device)
1875{
1876 struct dasd_eckd_private *private = device->private;
1877
1878 return private->eps.warn_thrshld;
1879}
1880
1881static int dasd_eckd_ext_pool_cap_at_warnlevel(struct dasd_device *device)
1882{
1883 struct dasd_eckd_private *private = device->private;
1884
1885 return private->eps.flags.capacity_at_warnlevel;
1886}
1887
1888
1889
1890
1891static int dasd_eckd_ext_pool_oos(struct dasd_device *device)
1892{
1893 struct dasd_eckd_private *private = device->private;
1894
1895 return private->eps.flags.pool_oos;
1896}
1897
1898
1899
1900
1901static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
1902 int enable_pav)
1903{
1904 struct dasd_ccw_req *cqr;
1905 struct dasd_psf_ssc_data *psf_ssc_data;
1906 struct ccw1 *ccw;
1907
1908 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 ,
1909 sizeof(struct dasd_psf_ssc_data),
1910 device, NULL);
1911
1912 if (IS_ERR(cqr)) {
1913 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
1914 "Could not allocate PSF-SSC request");
1915 return cqr;
1916 }
1917 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
1918 psf_ssc_data->order = PSF_ORDER_SSC;
1919 psf_ssc_data->suborder = 0xc0;
1920 if (enable_pav) {
1921 psf_ssc_data->suborder |= 0x08;
1922 psf_ssc_data->reserved[0] = 0x88;
1923 }
1924 ccw = cqr->cpaddr;
1925 ccw->cmd_code = DASD_ECKD_CCW_PSF;
1926 ccw->cda = (__u32)(addr_t)psf_ssc_data;
1927 ccw->count = 66;
1928
1929 cqr->startdev = device;
1930 cqr->memdev = device;
1931 cqr->block = NULL;
1932 cqr->retries = 256;
1933 cqr->expires = 10*HZ;
1934 cqr->buildclk = get_tod_clock();
1935 cqr->status = DASD_CQR_FILLED;
1936 return cqr;
1937}
1938
1939
1940
1941
1942
1943
1944static int
1945dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav,
1946 unsigned long flags)
1947{
1948 struct dasd_ccw_req *cqr;
1949 int rc;
1950
1951 cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
1952 if (IS_ERR(cqr))
1953 return PTR_ERR(cqr);
1954
1955
1956
1957
1958
1959 cqr->flags |= flags;
1960
1961 rc = dasd_sleep_on(cqr);
1962 if (!rc)
1963
1964 css_schedule_reprobe();
1965 else if (cqr->intrc == -EAGAIN)
1966 rc = -EAGAIN;
1967
1968 dasd_sfree_request(cqr, cqr->memdev);
1969 return rc;
1970}
1971
1972
1973
1974
1975static int dasd_eckd_validate_server(struct dasd_device *device,
1976 unsigned long flags)
1977{
1978 struct dasd_eckd_private *private = device->private;
1979 int enable_pav, rc;
1980
1981 if (private->uid.type == UA_BASE_PAV_ALIAS ||
1982 private->uid.type == UA_HYPER_PAV_ALIAS)
1983 return 0;
1984 if (dasd_nopav || MACHINE_IS_VM)
1985 enable_pav = 0;
1986 else
1987 enable_pav = 1;
1988 rc = dasd_eckd_psf_ssc(device, enable_pav, flags);
1989
1990
1991
1992 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
1993 "returned rc=%d", private->uid.ssid, rc);
1994 return rc;
1995}
1996
1997
1998
1999
2000static void dasd_eckd_do_validate_server(struct work_struct *work)
2001{
2002 struct dasd_device *device = container_of(work, struct dasd_device,
2003 kick_validate);
2004 unsigned long flags = 0;
2005
2006 set_bit(DASD_CQR_FLAGS_FAILFAST, &flags);
2007 if (dasd_eckd_validate_server(device, flags)
2008 == -EAGAIN) {
2009
2010 schedule_work(&device->kick_validate);
2011 return;
2012 }
2013
2014 dasd_put_device(device);
2015}
2016
2017static void dasd_eckd_kick_validate_server(struct dasd_device *device)
2018{
2019 dasd_get_device(device);
2020
2021 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
2022 device->state < DASD_STATE_ONLINE) {
2023 dasd_put_device(device);
2024 return;
2025 }
2026
2027 if (!schedule_work(&device->kick_validate))
2028 dasd_put_device(device);
2029}
2030
2031
2032
2033
2034
2035static int
2036dasd_eckd_check_characteristics(struct dasd_device *device)
2037{
2038 struct dasd_eckd_private *private = device->private;
2039 struct dasd_block *block;
2040 struct dasd_uid temp_uid;
2041 int rc, i;
2042 int readonly;
2043 unsigned long value;
2044
2045
2046 INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server);
2047
2048 INIT_WORK(&device->suc_work, dasd_alias_handle_summary_unit_check);
2049
2050 if (!ccw_device_is_pathgroup(device->cdev)) {
2051 dev_warn(&device->cdev->dev,
2052 "A channel path group could not be established\n");
2053 return -EIO;
2054 }
2055 if (!ccw_device_is_multipath(device->cdev)) {
2056 dev_info(&device->cdev->dev,
2057 "The DASD is not operating in multipath mode\n");
2058 }
2059 if (!private) {
2060 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
2061 if (!private) {
2062 dev_warn(&device->cdev->dev,
2063 "Allocating memory for private DASD data "
2064 "failed\n");
2065 return -ENOMEM;
2066 }
2067 device->private = private;
2068 } else {
2069 memset(private, 0, sizeof(*private));
2070 }
2071
2072 private->init_cqr_status = -1;
2073
2074 private->attrib.operation = DASD_NORMAL_CACHE;
2075 private->attrib.nr_cyl = 0;
2076
2077
2078 rc = dasd_eckd_read_conf(device);
2079 if (rc)
2080 goto out_err1;
2081
2082
2083 device->default_expires = DASD_EXPIRES;
2084 device->default_retries = DASD_RETRIES;
2085 device->path_thrhld = DASD_ECKD_PATH_THRHLD;
2086 device->path_interval = DASD_ECKD_PATH_INTERVAL;
2087
2088 if (private->gneq) {
2089 value = 1;
2090 for (i = 0; i < private->gneq->timeout.value; i++)
2091 value = 10 * value;
2092 value = value * private->gneq->timeout.number;
2093
2094 if (value != 0 && value <= DASD_EXPIRES_MAX)
2095 device->default_expires = value;
2096 }
2097
2098 dasd_eckd_get_uid(device, &temp_uid);
2099 if (temp_uid.type == UA_BASE_DEVICE) {
2100 block = dasd_alloc_block();
2101 if (IS_ERR(block)) {
2102 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
2103 "could not allocate dasd "
2104 "block structure");
2105 rc = PTR_ERR(block);
2106 goto out_err1;
2107 }
2108 device->block = block;
2109 block->base = device;
2110 }
2111
2112
2113 rc = dasd_alias_make_device_known_to_lcu(device);
2114 if (rc)
2115 goto out_err2;
2116
2117 dasd_eckd_validate_server(device, 0);
2118
2119
2120 rc = dasd_eckd_read_conf(device);
2121 if (rc)
2122 goto out_err3;
2123
2124 dasd_path_create_kobjects(device);
2125
2126
2127 dasd_eckd_read_features(device);
2128
2129
2130 dasd_eckd_read_vol_info(device);
2131
2132
2133 dasd_eckd_read_ext_pool_info(device);
2134
2135
2136 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
2137 &private->rdc_data, 64);
2138 if (rc) {
2139 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
2140 "Read device characteristic failed, rc=%d", rc);
2141 goto out_err3;
2142 }
2143
2144 if ((device->features & DASD_FEATURE_USERAW) &&
2145 !(private->rdc_data.facilities.RT_in_LR)) {
2146 dev_err(&device->cdev->dev, "The storage server does not "
2147 "support raw-track access\n");
2148 rc = -EINVAL;
2149 goto out_err3;
2150 }
2151
2152
2153 if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
2154 private->rdc_data.long_no_cyl)
2155 private->real_cyl = private->rdc_data.long_no_cyl;
2156 else
2157 private->real_cyl = private->rdc_data.no_cyl;
2158
2159 private->fcx_max_data = get_fcx_max_data(device);
2160
2161 readonly = dasd_device_is_ro(device);
2162 if (readonly)
2163 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
2164
2165 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
2166 "with %d cylinders, %d heads, %d sectors%s\n",
2167 private->rdc_data.dev_type,
2168 private->rdc_data.dev_model,
2169 private->rdc_data.cu_type,
2170 private->rdc_data.cu_model.model,
2171 private->real_cyl,
2172 private->rdc_data.trk_per_cyl,
2173 private->rdc_data.sec_per_trk,
2174 readonly ? ", read-only device" : "");
2175 return 0;
2176
2177out_err3:
2178 dasd_alias_disconnect_device_from_lcu(device);
2179out_err2:
2180 dasd_free_block(device->block);
2181 device->block = NULL;
2182out_err1:
2183 dasd_eckd_clear_conf_data(device);
2184 dasd_path_remove_kobjects(device);
2185 kfree(device->private);
2186 device->private = NULL;
2187 return rc;
2188}
2189
2190static void dasd_eckd_uncheck_device(struct dasd_device *device)
2191{
2192 struct dasd_eckd_private *private = device->private;
2193
2194 if (!private)
2195 return;
2196
2197 dasd_alias_disconnect_device_from_lcu(device);
2198 private->ned = NULL;
2199 private->sneq = NULL;
2200 private->vdsneq = NULL;
2201 private->gneq = NULL;
2202 dasd_eckd_clear_conf_data(device);
2203 dasd_path_remove_kobjects(device);
2204}
2205
2206static struct dasd_ccw_req *
2207dasd_eckd_analysis_ccw(struct dasd_device *device)
2208{
2209 struct dasd_eckd_private *private = device->private;
2210 struct eckd_count *count_data;
2211 struct LO_eckd_data *LO_data;
2212 struct dasd_ccw_req *cqr;
2213 struct ccw1 *ccw;
2214 int cplength, datasize;
2215 int i;
2216
2217 cplength = 8;
2218 datasize = sizeof(struct DE_eckd_data) + 2*sizeof(struct LO_eckd_data);
2219 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize, device,
2220 NULL);
2221 if (IS_ERR(cqr))
2222 return cqr;
2223 ccw = cqr->cpaddr;
2224
2225 define_extent(ccw++, cqr->data, 0, 1,
2226 DASD_ECKD_CCW_READ_COUNT, device, 0);
2227 LO_data = cqr->data + sizeof(struct DE_eckd_data);
2228
2229 ccw[-1].flags |= CCW_FLAG_CC;
2230 locate_record(ccw++, LO_data++, 0, 0, 4,
2231 DASD_ECKD_CCW_READ_COUNT, device, 0);
2232
2233 count_data = private->count_area;
2234 for (i = 0; i < 4; i++) {
2235 ccw[-1].flags |= CCW_FLAG_CC;
2236 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
2237 ccw->flags = 0;
2238 ccw->count = 8;
2239 ccw->cda = (__u32)(addr_t) count_data;
2240 ccw++;
2241 count_data++;
2242 }
2243
2244
2245 ccw[-1].flags |= CCW_FLAG_CC;
2246 locate_record(ccw++, LO_data++, 1, 0, 1,
2247 DASD_ECKD_CCW_READ_COUNT, device, 0);
2248
2249 ccw[-1].flags |= CCW_FLAG_CC;
2250 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
2251 ccw->flags = 0;
2252 ccw->count = 8;
2253 ccw->cda = (__u32)(addr_t) count_data;
2254
2255 cqr->block = NULL;
2256 cqr->startdev = device;
2257 cqr->memdev = device;
2258 cqr->retries = 255;
2259 cqr->buildclk = get_tod_clock();
2260 cqr->status = DASD_CQR_FILLED;
2261
2262 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
2263
2264 return cqr;
2265}
2266
2267
2268static int dasd_eckd_analysis_evaluation(struct dasd_ccw_req *init_cqr)
2269{
2270 char *sense;
2271 if (init_cqr->status == DASD_CQR_DONE)
2272 return INIT_CQR_OK;
2273 else if (init_cqr->status == DASD_CQR_NEED_ERP ||
2274 init_cqr->status == DASD_CQR_FAILED) {
2275 sense = dasd_get_sense(&init_cqr->irb);
2276 if (sense && (sense[1] & SNS1_NO_REC_FOUND))
2277 return INIT_CQR_UNFORMATTED;
2278 else
2279 return INIT_CQR_ERROR;
2280 } else
2281 return INIT_CQR_ERROR;
2282}
2283
2284
2285
2286
2287
2288
2289
2290
2291static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr,
2292 void *data)
2293{
2294 struct dasd_device *device = init_cqr->startdev;
2295 struct dasd_eckd_private *private = device->private;
2296
2297 private->init_cqr_status = dasd_eckd_analysis_evaluation(init_cqr);
2298 dasd_sfree_request(init_cqr, device);
2299 dasd_kick_device(device);
2300}
2301
2302static int dasd_eckd_start_analysis(struct dasd_block *block)
2303{
2304 struct dasd_ccw_req *init_cqr;
2305
2306 init_cqr = dasd_eckd_analysis_ccw(block->base);
2307 if (IS_ERR(init_cqr))
2308 return PTR_ERR(init_cqr);
2309 init_cqr->callback = dasd_eckd_analysis_callback;
2310 init_cqr->callback_data = NULL;
2311 init_cqr->expires = 5*HZ;
2312
2313
2314
2315 clear_bit(DASD_CQR_FLAGS_USE_ERP, &init_cqr->flags);
2316 init_cqr->retries = 0;
2317 dasd_add_request_head(init_cqr);
2318 return -EAGAIN;
2319}
2320
2321static int dasd_eckd_end_analysis(struct dasd_block *block)
2322{
2323 struct dasd_device *device = block->base;
2324 struct dasd_eckd_private *private = device->private;
2325 struct eckd_count *count_area;
2326 unsigned int sb, blk_per_trk;
2327 int status, i;
2328 struct dasd_ccw_req *init_cqr;
2329
2330 status = private->init_cqr_status;
2331 private->init_cqr_status = -1;
2332 if (status == INIT_CQR_ERROR) {
2333
2334 init_cqr = dasd_eckd_analysis_ccw(device);
2335 dasd_sleep_on(init_cqr);
2336 status = dasd_eckd_analysis_evaluation(init_cqr);
2337 dasd_sfree_request(init_cqr, device);
2338 }
2339
2340 if (device->features & DASD_FEATURE_USERAW) {
2341 block->bp_block = DASD_RAW_BLOCKSIZE;
2342 blk_per_trk = DASD_RAW_BLOCK_PER_TRACK;
2343 block->s2b_shift = 3;
2344 goto raw;
2345 }
2346
2347 if (status == INIT_CQR_UNFORMATTED) {
2348 dev_warn(&device->cdev->dev, "The DASD is not formatted\n");
2349 return -EMEDIUMTYPE;
2350 } else if (status == INIT_CQR_ERROR) {
2351 dev_err(&device->cdev->dev,
2352 "Detecting the DASD disk layout failed because "
2353 "of an I/O error\n");
2354 return -EIO;
2355 }
2356
2357 private->uses_cdl = 1;
2358
2359 count_area = NULL;
2360 for (i = 0; i < 3; i++) {
2361 if (private->count_area[i].kl != 4 ||
2362 private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4 ||
2363 private->count_area[i].cyl != 0 ||
2364 private->count_area[i].head != count_area_head[i] ||
2365 private->count_area[i].record != count_area_rec[i]) {
2366 private->uses_cdl = 0;
2367 break;
2368 }
2369 }
2370 if (i == 3)
2371 count_area = &private->count_area[3];
2372
2373 if (private->uses_cdl == 0) {
2374 for (i = 0; i < 5; i++) {
2375 if ((private->count_area[i].kl != 0) ||
2376 (private->count_area[i].dl !=
2377 private->count_area[0].dl) ||
2378 private->count_area[i].cyl != 0 ||
2379 private->count_area[i].head != count_area_head[i] ||
2380 private->count_area[i].record != count_area_rec[i])
2381 break;
2382 }
2383 if (i == 5)
2384 count_area = &private->count_area[0];
2385 } else {
2386 if (private->count_area[3].record == 1)
2387 dev_warn(&device->cdev->dev,
2388 "Track 0 has no records following the VTOC\n");
2389 }
2390
2391 if (count_area != NULL && count_area->kl == 0) {
2392
2393 if (dasd_check_blocksize(count_area->dl) == 0)
2394 block->bp_block = count_area->dl;
2395 }
2396 if (block->bp_block == 0) {
2397 dev_warn(&device->cdev->dev,
2398 "The disk layout of the DASD is not supported\n");
2399 return -EMEDIUMTYPE;
2400 }
2401 block->s2b_shift = 0;
2402 for (sb = 512; sb < block->bp_block; sb = sb << 1)
2403 block->s2b_shift++;
2404
2405 blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
2406
2407raw:
2408 block->blocks = (private->real_cyl *
2409 private->rdc_data.trk_per_cyl *
2410 blk_per_trk);
2411
2412 dev_info(&device->cdev->dev,
2413 "DASD with %d KB/block, %d KB total size, %d KB/track, "
2414 "%s\n", (block->bp_block >> 10),
2415 ((private->real_cyl *
2416 private->rdc_data.trk_per_cyl *
2417 blk_per_trk * (block->bp_block >> 9)) >> 1),
2418 ((blk_per_trk * block->bp_block) >> 10),
2419 private->uses_cdl ?
2420 "compatible disk layout" : "linux disk layout");
2421
2422 return 0;
2423}
2424
2425static int dasd_eckd_do_analysis(struct dasd_block *block)
2426{
2427 struct dasd_eckd_private *private = block->base->private;
2428
2429 if (private->init_cqr_status < 0)
2430 return dasd_eckd_start_analysis(block);
2431 else
2432 return dasd_eckd_end_analysis(block);
2433}
2434
2435static int dasd_eckd_basic_to_ready(struct dasd_device *device)
2436{
2437 return dasd_alias_add_device(device);
2438};
2439
2440static int dasd_eckd_online_to_ready(struct dasd_device *device)
2441{
2442 cancel_work_sync(&device->reload_device);
2443 cancel_work_sync(&device->kick_validate);
2444 return 0;
2445};
2446
2447static int dasd_eckd_basic_to_known(struct dasd_device *device)
2448{
2449 return dasd_alias_remove_device(device);
2450};
2451
2452static int
2453dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo)
2454{
2455 struct dasd_eckd_private *private = block->base->private;
2456
2457 if (dasd_check_blocksize(block->bp_block) == 0) {
2458 geo->sectors = recs_per_track(&private->rdc_data,
2459 0, block->bp_block);
2460 }
2461 geo->cylinders = private->rdc_data.no_cyl;
2462 geo->heads = private->rdc_data.trk_per_cyl;
2463 return 0;
2464}
2465
2466
2467
2468
2469static struct dasd_ccw_req *
2470dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata,
2471 int enable_pav, struct eckd_count *fmt_buffer,
2472 int rpt)
2473{
2474 struct dasd_eckd_private *start_priv;
2475 struct dasd_device *startdev = NULL;
2476 struct tidaw *last_tidaw = NULL;
2477 struct dasd_ccw_req *cqr;
2478 struct itcw *itcw;
2479 int itcw_size;
2480 int count;
2481 int rc;
2482 int i;
2483
2484 if (enable_pav)
2485 startdev = dasd_alias_get_start_dev(base);
2486
2487 if (!startdev)
2488 startdev = base;
2489
2490 start_priv = startdev->private;
2491
2492 count = rpt * (fdata->stop_unit - fdata->start_unit + 1);
2493
2494
2495
2496
2497
2498 itcw_size = itcw_calc_size(0, count, 0);
2499
2500 cqr = dasd_fmalloc_request(DASD_ECKD_MAGIC, 0, itcw_size, startdev);
2501 if (IS_ERR(cqr))
2502 return cqr;
2503
2504 start_priv->count++;
2505
2506 itcw = itcw_init(cqr->data, itcw_size, ITCW_OP_READ, 0, count, 0);
2507 if (IS_ERR(itcw)) {
2508 rc = -EINVAL;
2509 goto out_err;
2510 }
2511
2512 cqr->cpaddr = itcw_get_tcw(itcw);
2513 rc = prepare_itcw(itcw, fdata->start_unit, fdata->stop_unit,
2514 DASD_ECKD_CCW_READ_COUNT_MT, base, startdev, 0, count,
2515 sizeof(struct eckd_count),
2516 count * sizeof(struct eckd_count), 0, rpt);
2517 if (rc)
2518 goto out_err;
2519
2520 for (i = 0; i < count; i++) {
2521 last_tidaw = itcw_add_tidaw(itcw, 0, fmt_buffer++,
2522 sizeof(struct eckd_count));
2523 if (IS_ERR(last_tidaw)) {
2524 rc = -EINVAL;
2525 goto out_err;
2526 }
2527 }
2528
2529 last_tidaw->flags |= TIDAW_FLAGS_LAST;
2530 itcw_finalize(itcw);
2531
2532 cqr->cpmode = 1;
2533 cqr->startdev = startdev;
2534 cqr->memdev = startdev;
2535 cqr->basedev = base;
2536 cqr->retries = startdev->default_retries;
2537 cqr->expires = startdev->default_expires * HZ;
2538 cqr->buildclk = get_tod_clock();
2539 cqr->status = DASD_CQR_FILLED;
2540
2541 set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
2542 set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
2543
2544 return cqr;
2545
2546out_err:
2547 dasd_sfree_request(cqr, startdev);
2548
2549 return ERR_PTR(rc);
2550}
2551
2552
2553
2554
2555static struct dasd_ccw_req *
2556dasd_eckd_build_check(struct dasd_device *base, struct format_data_t *fdata,
2557 int enable_pav, struct eckd_count *fmt_buffer, int rpt)
2558{
2559 struct dasd_eckd_private *start_priv;
2560 struct dasd_eckd_private *base_priv;
2561 struct dasd_device *startdev = NULL;
2562 struct dasd_ccw_req *cqr;
2563 struct ccw1 *ccw;
2564 void *data;
2565 int cplength, datasize;
2566 int use_prefix;
2567 int count;
2568 int i;
2569
2570 if (enable_pav)
2571 startdev = dasd_alias_get_start_dev(base);
2572
2573 if (!startdev)
2574 startdev = base;
2575
2576 start_priv = startdev->private;
2577 base_priv = base->private;
2578
2579 count = rpt * (fdata->stop_unit - fdata->start_unit + 1);
2580
2581 use_prefix = base_priv->features.feature[8] & 0x01;
2582
2583 if (use_prefix) {
2584 cplength = 1;
2585 datasize = sizeof(struct PFX_eckd_data);
2586 } else {
2587 cplength = 2;
2588 datasize = sizeof(struct DE_eckd_data) +
2589 sizeof(struct LO_eckd_data);
2590 }
2591 cplength += count;
2592
2593 cqr = dasd_fmalloc_request(DASD_ECKD_MAGIC, cplength, datasize, startdev);
2594 if (IS_ERR(cqr))
2595 return cqr;
2596
2597 start_priv->count++;
2598 data = cqr->data;
2599 ccw = cqr->cpaddr;
2600
2601 if (use_prefix) {
2602 prefix_LRE(ccw++, data, fdata->start_unit, fdata->stop_unit,
2603 DASD_ECKD_CCW_READ_COUNT, base, startdev, 1, 0,
2604 count, 0, 0);
2605 } else {
2606 define_extent(ccw++, data, fdata->start_unit, fdata->stop_unit,
2607 DASD_ECKD_CCW_READ_COUNT, startdev, 0);
2608
2609 data += sizeof(struct DE_eckd_data);
2610 ccw[-1].flags |= CCW_FLAG_CC;
2611
2612 locate_record(ccw++, data, fdata->start_unit, 0, count,
2613 DASD_ECKD_CCW_READ_COUNT, base, 0);
2614 }
2615
2616 for (i = 0; i < count; i++) {
2617 ccw[-1].flags |= CCW_FLAG_CC;
2618 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
2619 ccw->flags = CCW_FLAG_SLI;
2620 ccw->count = 8;
2621 ccw->cda = (__u32)(addr_t) fmt_buffer;
2622 ccw++;
2623 fmt_buffer++;
2624 }
2625
2626 cqr->startdev = startdev;
2627 cqr->memdev = startdev;
2628 cqr->basedev = base;
2629 cqr->retries = DASD_RETRIES;
2630 cqr->expires = startdev->default_expires * HZ;
2631 cqr->buildclk = get_tod_clock();
2632 cqr->status = DASD_CQR_FILLED;
2633
2634 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
2635
2636 return cqr;
2637}
2638
2639static struct dasd_ccw_req *
2640dasd_eckd_build_format(struct dasd_device *base, struct dasd_device *startdev,
2641 struct format_data_t *fdata, int enable_pav)
2642{
2643 struct dasd_eckd_private *base_priv;
2644 struct dasd_eckd_private *start_priv;
2645 struct dasd_ccw_req *fcp;
2646 struct eckd_count *ect;
2647 struct ch_t address;
2648 struct ccw1 *ccw;
2649 void *data;
2650 int rpt;
2651 int cplength, datasize;
2652 int i, j;
2653 int intensity = 0;
2654 int r0_perm;
2655 int nr_tracks;
2656 int use_prefix;
2657
2658 if (enable_pav)
2659 startdev = dasd_alias_get_start_dev(base);
2660
2661 if (!startdev)
2662 startdev = base;
2663
2664 start_priv = startdev->private;
2665 base_priv = base->private;
2666
2667 rpt = recs_per_track(&base_priv->rdc_data, 0, fdata->blksize);
2668
2669 nr_tracks = fdata->stop_unit - fdata->start_unit + 1;
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680 if (fdata->intensity & 0x10) {
2681 r0_perm = 0;
2682 intensity = fdata->intensity & ~0x10;
2683 } else {
2684 r0_perm = 1;
2685 intensity = fdata->intensity;
2686 }
2687
2688 use_prefix = base_priv->features.feature[8] & 0x01;
2689
2690 switch (intensity) {
2691 case 0x00:
2692 case 0x08:
2693 cplength = 2 + (rpt*nr_tracks);
2694 if (use_prefix)
2695 datasize = sizeof(struct PFX_eckd_data) +
2696 sizeof(struct LO_eckd_data) +
2697 rpt * nr_tracks * sizeof(struct eckd_count);
2698 else
2699 datasize = sizeof(struct DE_eckd_data) +
2700 sizeof(struct LO_eckd_data) +
2701 rpt * nr_tracks * sizeof(struct eckd_count);
2702 break;
2703 case 0x01:
2704 case 0x09:
2705 cplength = 2 + rpt * nr_tracks;
2706 if (use_prefix)
2707 datasize = sizeof(struct PFX_eckd_data) +
2708 sizeof(struct LO_eckd_data) +
2709 sizeof(struct eckd_count) +
2710 rpt * nr_tracks * sizeof(struct eckd_count);
2711 else
2712 datasize = sizeof(struct DE_eckd_data) +
2713 sizeof(struct LO_eckd_data) +
2714 sizeof(struct eckd_count) +
2715 rpt * nr_tracks * sizeof(struct eckd_count);
2716 break;
2717 case 0x04:
2718 case 0x0c:
2719 cplength = 3;
2720 if (use_prefix)
2721 datasize = sizeof(struct PFX_eckd_data) +
2722 sizeof(struct LO_eckd_data) +
2723 sizeof(struct eckd_count);
2724 else
2725 datasize = sizeof(struct DE_eckd_data) +
2726 sizeof(struct LO_eckd_data) +
2727 sizeof(struct eckd_count);
2728 break;
2729 default:
2730 dev_warn(&startdev->cdev->dev,
2731 "An I/O control call used incorrect flags 0x%x\n",
2732 fdata->intensity);
2733 return ERR_PTR(-EINVAL);
2734 }
2735
2736 fcp = dasd_fmalloc_request(DASD_ECKD_MAGIC, cplength, datasize, startdev);
2737 if (IS_ERR(fcp))
2738 return fcp;
2739
2740 start_priv->count++;
2741 data = fcp->data;
2742 ccw = fcp->cpaddr;
2743
2744 switch (intensity & ~0x08) {
2745 case 0x00:
2746 if (use_prefix) {
2747 prefix(ccw++, (struct PFX_eckd_data *) data,
2748 fdata->start_unit, fdata->stop_unit,
2749 DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2750
2751 if (r0_perm)
2752 ((struct PFX_eckd_data *)data)
2753 ->define_extent.ga_extended |= 0x04;
2754 data += sizeof(struct PFX_eckd_data);
2755 } else {
2756 define_extent(ccw++, (struct DE_eckd_data *) data,
2757 fdata->start_unit, fdata->stop_unit,
2758 DASD_ECKD_CCW_WRITE_CKD, startdev, 0);
2759
2760 if (r0_perm)
2761 ((struct DE_eckd_data *) data)
2762 ->ga_extended |= 0x04;
2763 data += sizeof(struct DE_eckd_data);
2764 }
2765 ccw[-1].flags |= CCW_FLAG_CC;
2766 locate_record(ccw++, (struct LO_eckd_data *) data,
2767 fdata->start_unit, 0, rpt*nr_tracks,
2768 DASD_ECKD_CCW_WRITE_CKD, base,
2769 fdata->blksize);
2770 data += sizeof(struct LO_eckd_data);
2771 break;
2772 case 0x01:
2773 if (use_prefix) {
2774 prefix(ccw++, (struct PFX_eckd_data *) data,
2775 fdata->start_unit, fdata->stop_unit,
2776 DASD_ECKD_CCW_WRITE_RECORD_ZERO,
2777 base, startdev);
2778 data += sizeof(struct PFX_eckd_data);
2779 } else {
2780 define_extent(ccw++, (struct DE_eckd_data *) data,
2781 fdata->start_unit, fdata->stop_unit,
2782 DASD_ECKD_CCW_WRITE_RECORD_ZERO, startdev, 0);
2783 data += sizeof(struct DE_eckd_data);
2784 }
2785 ccw[-1].flags |= CCW_FLAG_CC;
2786 locate_record(ccw++, (struct LO_eckd_data *) data,
2787 fdata->start_unit, 0, rpt * nr_tracks + 1,
2788 DASD_ECKD_CCW_WRITE_RECORD_ZERO, base,
2789 base->block->bp_block);
2790 data += sizeof(struct LO_eckd_data);
2791 break;
2792 case 0x04:
2793 if (use_prefix) {
2794 prefix(ccw++, (struct PFX_eckd_data *) data,
2795 fdata->start_unit, fdata->stop_unit,
2796 DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2797 data += sizeof(struct PFX_eckd_data);
2798 } else {
2799 define_extent(ccw++, (struct DE_eckd_data *) data,
2800 fdata->start_unit, fdata->stop_unit,
2801 DASD_ECKD_CCW_WRITE_CKD, startdev, 0);
2802 data += sizeof(struct DE_eckd_data);
2803 }
2804 ccw[-1].flags |= CCW_FLAG_CC;
2805 locate_record(ccw++, (struct LO_eckd_data *) data,
2806 fdata->start_unit, 0, 1,
2807 DASD_ECKD_CCW_WRITE_CKD, base, 8);
2808 data += sizeof(struct LO_eckd_data);
2809 break;
2810 }
2811
2812 for (j = 0; j < nr_tracks; j++) {
2813
2814 set_ch_t(&address,
2815 (fdata->start_unit + j) /
2816 base_priv->rdc_data.trk_per_cyl,
2817 (fdata->start_unit + j) %
2818 base_priv->rdc_data.trk_per_cyl);
2819 if (intensity & 0x01) {
2820 ect = (struct eckd_count *) data;
2821 data += sizeof(struct eckd_count);
2822 ect->cyl = address.cyl;
2823 ect->head = address.head;
2824 ect->record = 0;
2825 ect->kl = 0;
2826 ect->dl = 8;
2827 ccw[-1].flags |= CCW_FLAG_CC;
2828 ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO;
2829 ccw->flags = CCW_FLAG_SLI;
2830 ccw->count = 8;
2831 ccw->cda = (__u32)(addr_t) ect;
2832 ccw++;
2833 }
2834 if ((intensity & ~0x08) & 0x04) {
2835 ect = (struct eckd_count *) data;
2836 data += sizeof(struct eckd_count);
2837 ect->cyl = address.cyl;
2838 ect->head = address.head;
2839 ect->record = 1;
2840 ect->kl = 0;
2841 ect->dl = 0;
2842 ccw[-1].flags |= CCW_FLAG_CC;
2843 ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;
2844 ccw->flags = CCW_FLAG_SLI;
2845 ccw->count = 8;
2846 ccw->cda = (__u32)(addr_t) ect;
2847 } else {
2848 for (i = 0; i < rpt; i++) {
2849 ect = (struct eckd_count *) data;
2850 data += sizeof(struct eckd_count);
2851 ect->cyl = address.cyl;
2852 ect->head = address.head;
2853 ect->record = i + 1;
2854 ect->kl = 0;
2855 ect->dl = fdata->blksize;
2856
2857
2858
2859
2860 if ((intensity & 0x08) &&
2861 address.cyl == 0 && address.head == 0) {
2862 if (i < 3) {
2863 ect->kl = 4;
2864 ect->dl = sizes_trk0[i] - 4;
2865 }
2866 }
2867 if ((intensity & 0x08) &&
2868 address.cyl == 0 && address.head == 1) {
2869 ect->kl = 44;
2870 ect->dl = LABEL_SIZE - 44;
2871 }
2872 ccw[-1].flags |= CCW_FLAG_CC;
2873 if (i != 0 || j == 0)
2874 ccw->cmd_code =
2875 DASD_ECKD_CCW_WRITE_CKD;
2876 else
2877 ccw->cmd_code =
2878 DASD_ECKD_CCW_WRITE_CKD_MT;
2879 ccw->flags = CCW_FLAG_SLI;
2880 ccw->count = 8;
2881 ccw->cda = (__u32)(addr_t) ect;
2882 ccw++;
2883 }
2884 }
2885 }
2886
2887 fcp->startdev = startdev;
2888 fcp->memdev = startdev;
2889 fcp->basedev = base;
2890 fcp->retries = 256;
2891 fcp->expires = startdev->default_expires * HZ;
2892 fcp->buildclk = get_tod_clock();
2893 fcp->status = DASD_CQR_FILLED;
2894
2895 return fcp;
2896}
2897
2898
2899
2900
2901static struct dasd_ccw_req *
2902dasd_eckd_format_build_ccw_req(struct dasd_device *base,
2903 struct format_data_t *fdata, int enable_pav,
2904 int tpm, struct eckd_count *fmt_buffer, int rpt)
2905{
2906 struct dasd_ccw_req *ccw_req;
2907
2908 if (!fmt_buffer) {
2909 ccw_req = dasd_eckd_build_format(base, NULL, fdata, enable_pav);
2910 } else {
2911 if (tpm)
2912 ccw_req = dasd_eckd_build_check_tcw(base, fdata,
2913 enable_pav,
2914 fmt_buffer, rpt);
2915 else
2916 ccw_req = dasd_eckd_build_check(base, fdata, enable_pav,
2917 fmt_buffer, rpt);
2918 }
2919
2920 return ccw_req;
2921}
2922
2923
2924
2925
2926static int dasd_eckd_format_sanity_checks(struct dasd_device *base,
2927 struct format_data_t *fdata)
2928{
2929 struct dasd_eckd_private *private = base->private;
2930
2931 if (fdata->start_unit >=
2932 (private->real_cyl * private->rdc_data.trk_per_cyl)) {
2933 dev_warn(&base->cdev->dev,
2934 "Start track number %u used in formatting is too big\n",
2935 fdata->start_unit);
2936 return -EINVAL;
2937 }
2938 if (fdata->stop_unit >=
2939 (private->real_cyl * private->rdc_data.trk_per_cyl)) {
2940 dev_warn(&base->cdev->dev,
2941 "Stop track number %u used in formatting is too big\n",
2942 fdata->stop_unit);
2943 return -EINVAL;
2944 }
2945 if (fdata->start_unit > fdata->stop_unit) {
2946 dev_warn(&base->cdev->dev,
2947 "Start track %u used in formatting exceeds end track\n",
2948 fdata->start_unit);
2949 return -EINVAL;
2950 }
2951 if (dasd_check_blocksize(fdata->blksize) != 0) {
2952 dev_warn(&base->cdev->dev,
2953 "The DASD cannot be formatted with block size %u\n",
2954 fdata->blksize);
2955 return -EINVAL;
2956 }
2957 return 0;
2958}
2959
2960
2961
2962
2963static int dasd_eckd_format_process_data(struct dasd_device *base,
2964 struct format_data_t *fdata,
2965 int enable_pav, int tpm,
2966 struct eckd_count *fmt_buffer, int rpt,
2967 struct irb *irb)
2968{
2969 struct dasd_eckd_private *private = base->private;
2970 struct dasd_ccw_req *cqr, *n;
2971 struct list_head format_queue;
2972 struct dasd_device *device;
2973 char *sense = NULL;
2974 int old_start, old_stop, format_step;
2975 int step, retry;
2976 int rc;
2977
2978 rc = dasd_eckd_format_sanity_checks(base, fdata);
2979 if (rc)
2980 return rc;
2981
2982 INIT_LIST_HEAD(&format_queue);
2983
2984 old_start = fdata->start_unit;
2985 old_stop = fdata->stop_unit;
2986
2987 if (!tpm && fmt_buffer != NULL) {
2988
2989 format_step = 1;
2990 } else if (tpm && fmt_buffer != NULL) {
2991
2992 format_step = DASD_CQR_MAX_CCW / rpt;
2993 } else {
2994
2995 format_step = DASD_CQR_MAX_CCW /
2996 recs_per_track(&private->rdc_data, 0, fdata->blksize);
2997 }
2998
2999 do {
3000 retry = 0;
3001 while (fdata->start_unit <= old_stop) {
3002 step = fdata->stop_unit - fdata->start_unit + 1;
3003 if (step > format_step) {
3004 fdata->stop_unit =
3005 fdata->start_unit + format_step - 1;
3006 }
3007
3008 cqr = dasd_eckd_format_build_ccw_req(base, fdata,
3009 enable_pav, tpm,
3010 fmt_buffer, rpt);
3011 if (IS_ERR(cqr)) {
3012 rc = PTR_ERR(cqr);
3013 if (rc == -ENOMEM) {
3014 if (list_empty(&format_queue))
3015 goto out;
3016
3017
3018
3019
3020
3021 retry = 1;
3022 break;
3023 }
3024 goto out_err;
3025 }
3026 list_add_tail(&cqr->blocklist, &format_queue);
3027
3028 if (fmt_buffer) {
3029 step = fdata->stop_unit - fdata->start_unit + 1;
3030 fmt_buffer += rpt * step;
3031 }
3032 fdata->start_unit = fdata->stop_unit + 1;
3033 fdata->stop_unit = old_stop;
3034 }
3035
3036 rc = dasd_sleep_on_queue(&format_queue);
3037
3038out_err:
3039 list_for_each_entry_safe(cqr, n, &format_queue, blocklist) {
3040 device = cqr->startdev;
3041 private = device->private;
3042
3043 if (cqr->status == DASD_CQR_FAILED) {
3044
3045
3046
3047
3048 if (fmt_buffer && irb) {
3049 sense = dasd_get_sense(&cqr->irb);
3050 memcpy(irb, &cqr->irb, sizeof(*irb));
3051 }
3052 rc = -EIO;
3053 }
3054 list_del_init(&cqr->blocklist);
3055 dasd_ffree_request(cqr, device);
3056 private->count--;
3057 }
3058
3059 if (rc && rc != -EIO)
3060 goto out;
3061 if (rc == -EIO) {
3062
3063
3064
3065
3066
3067
3068
3069
3070 if (sense &&
3071 (sense[1] & SNS1_NO_REC_FOUND ||
3072 sense[1] & SNS1_FILE_PROTECTED))
3073 retry = 1;
3074 else
3075 goto out;
3076 }
3077
3078 } while (retry);
3079
3080out:
3081 fdata->start_unit = old_start;
3082 fdata->stop_unit = old_stop;
3083
3084 return rc;
3085}
3086
3087static int dasd_eckd_format_device(struct dasd_device *base,
3088 struct format_data_t *fdata, int enable_pav)
3089{
3090 return dasd_eckd_format_process_data(base, fdata, enable_pav, 0, NULL,
3091 0, NULL);
3092}
3093
3094static bool test_and_set_format_track(struct dasd_format_entry *to_format,
3095 struct dasd_block *block)
3096{
3097 struct dasd_format_entry *format;
3098 unsigned long flags;
3099 bool rc = false;
3100
3101 spin_lock_irqsave(&block->format_lock, flags);
3102 list_for_each_entry(format, &block->format_list, list) {
3103 if (format->track == to_format->track) {
3104 rc = true;
3105 goto out;
3106 }
3107 }
3108 list_add_tail(&to_format->list, &block->format_list);
3109
3110out:
3111 spin_unlock_irqrestore(&block->format_lock, flags);
3112 return rc;
3113}
3114
3115static void clear_format_track(struct dasd_format_entry *format,
3116 struct dasd_block *block)
3117{
3118 unsigned long flags;
3119
3120 spin_lock_irqsave(&block->format_lock, flags);
3121 list_del_init(&format->list);
3122 spin_unlock_irqrestore(&block->format_lock, flags);
3123}
3124
3125
3126
3127
3128static void dasd_eckd_ese_format_cb(struct dasd_ccw_req *cqr, void *data)
3129{
3130 struct dasd_device *device = cqr->startdev;
3131 struct dasd_eckd_private *private = device->private;
3132 struct dasd_format_entry *format = data;
3133
3134 clear_format_track(format, cqr->basedev->block);
3135 private->count--;
3136 dasd_ffree_request(cqr, device);
3137}
3138
3139static struct dasd_ccw_req *
3140dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr,
3141 struct irb *irb)
3142{
3143 struct dasd_eckd_private *private;
3144 struct dasd_format_entry *format;
3145 struct format_data_t fdata;
3146 unsigned int recs_per_trk;
3147 struct dasd_ccw_req *fcqr;
3148 struct dasd_device *base;
3149 struct dasd_block *block;
3150 unsigned int blksize;
3151 struct request *req;
3152 sector_t first_trk;
3153 sector_t last_trk;
3154 sector_t curr_trk;
3155 int rc;
3156
3157 req = cqr->callback_data;
3158 block = cqr->block;
3159 base = block->base;
3160 private = base->private;
3161 blksize = block->bp_block;
3162 recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
3163 format = &startdev->format_entry;
3164
3165 first_trk = blk_rq_pos(req) >> block->s2b_shift;
3166 sector_div(first_trk, recs_per_trk);
3167 last_trk =
3168 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
3169 sector_div(last_trk, recs_per_trk);
3170 rc = dasd_eckd_track_from_irb(irb, base, &curr_trk);
3171 if (rc)
3172 return ERR_PTR(rc);
3173
3174 if (curr_trk < first_trk || curr_trk > last_trk) {
3175 DBF_DEV_EVENT(DBF_WARNING, startdev,
3176 "ESE error track %llu not within range %llu - %llu\n",
3177 curr_trk, first_trk, last_trk);
3178 return ERR_PTR(-EINVAL);
3179 }
3180 format->track = curr_trk;
3181
3182 if (test_and_set_format_track(format, block))
3183 return ERR_PTR(-EEXIST);
3184
3185 fdata.start_unit = curr_trk;
3186 fdata.stop_unit = curr_trk;
3187 fdata.blksize = blksize;
3188 fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0;
3189
3190 rc = dasd_eckd_format_sanity_checks(base, &fdata);
3191 if (rc)
3192 return ERR_PTR(-EINVAL);
3193
3194
3195
3196
3197
3198 fcqr = dasd_eckd_build_format(base, startdev, &fdata, 0);
3199 if (IS_ERR(fcqr))
3200 return fcqr;
3201
3202 fcqr->callback = dasd_eckd_ese_format_cb;
3203 fcqr->callback_data = (void *) format;
3204
3205 return fcqr;
3206}
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb)
3221{
3222 struct dasd_eckd_private *private;
3223 sector_t first_trk, last_trk;
3224 sector_t first_blk, last_blk;
3225 unsigned int blksize, off;
3226 unsigned int recs_per_trk;
3227 struct dasd_device *base;
3228 struct req_iterator iter;
3229 struct dasd_block *block;
3230 unsigned int skip_block;
3231 unsigned int blk_count;
3232 struct request *req;
3233 struct bio_vec bv;
3234 sector_t curr_trk;
3235 sector_t end_blk;
3236 char *dst;
3237 int rc;
3238
3239 req = (struct request *) cqr->callback_data;
3240 base = cqr->block->base;
3241 blksize = base->block->bp_block;
3242 block = cqr->block;
3243 private = base->private;
3244 skip_block = 0;
3245 blk_count = 0;
3246
3247 recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
3248 first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift;
3249 sector_div(first_trk, recs_per_trk);
3250 last_trk = last_blk =
3251 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
3252 sector_div(last_trk, recs_per_trk);
3253 rc = dasd_eckd_track_from_irb(irb, base, &curr_trk);
3254 if (rc)
3255 return rc;
3256
3257
3258 if (curr_trk < first_trk || curr_trk > last_trk) {
3259 DBF_DEV_EVENT(DBF_WARNING, base,
3260 "ESE error track %llu not within range %llu - %llu\n",
3261 curr_trk, first_trk, last_trk);
3262 return -EINVAL;
3263 }
3264
3265
3266
3267
3268
3269 if (curr_trk != first_trk)
3270 skip_block = curr_trk * recs_per_trk - first_blk;
3271
3272
3273 end_blk = (curr_trk + 1) * recs_per_trk;
3274
3275 rq_for_each_segment(bv, req, iter) {
3276 dst = page_address(bv.bv_page) + bv.bv_offset;
3277 for (off = 0; off < bv.bv_len; off += blksize) {
3278 if (first_blk + blk_count >= end_blk) {
3279 cqr->proc_bytes = blk_count * blksize;
3280 return 0;
3281 }
3282 if (dst && !skip_block) {
3283 dst += off;
3284 memset(dst, 0, blksize);
3285 } else {
3286 skip_block--;
3287 }
3288 blk_count++;
3289 }
3290 }
3291 return 0;
3292}
3293
3294
3295
3296
3297static int dasd_eckd_count_records(struct eckd_count *fmt_buffer, int start,
3298 int max)
3299{
3300 int head;
3301 int i;
3302
3303 head = fmt_buffer[start].head;
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314 for (i = start; i < max; i++) {
3315 if (i > start) {
3316 if ((fmt_buffer[i].head == head &&
3317 fmt_buffer[i].record == 1) ||
3318 fmt_buffer[i].head != head ||
3319 fmt_buffer[i].record == 0)
3320 break;
3321 }
3322 }
3323
3324 return i - start;
3325}
3326
3327
3328
3329
3330
3331
3332
3333
3334static void dasd_eckd_format_evaluate_tracks(struct eckd_count *fmt_buffer,
3335 struct format_check_t *cdata,
3336 int rpt_max, int rpt_exp,
3337 int trk_per_cyl, int tpm)
3338{
3339 struct ch_t geo;
3340 int max_entries;
3341 int count = 0;
3342 int trkcount;
3343 int blksize;
3344 int pos = 0;
3345 int i, j;
3346 int kl;
3347
3348 trkcount = cdata->expect.stop_unit - cdata->expect.start_unit + 1;
3349 max_entries = trkcount * rpt_max;
3350
3351 for (i = cdata->expect.start_unit; i <= cdata->expect.stop_unit; i++) {
3352
3353 if (tpm) {
3354 while (fmt_buffer[pos].record == 0 &&
3355 fmt_buffer[pos].dl == 0) {
3356 if (pos++ > max_entries)
3357 break;
3358 }
3359 } else {
3360 if (i != cdata->expect.start_unit)
3361 pos += rpt_max - count;
3362 }
3363
3364
3365 set_ch_t(&geo, i / trk_per_cyl, i % trk_per_cyl);
3366
3367
3368 count = dasd_eckd_count_records(fmt_buffer, pos, pos + rpt_max);
3369
3370 if (count < rpt_exp) {
3371 cdata->result = DASD_FMT_ERR_TOO_FEW_RECORDS;
3372 break;
3373 }
3374 if (count > rpt_exp) {
3375 cdata->result = DASD_FMT_ERR_TOO_MANY_RECORDS;
3376 break;
3377 }
3378
3379 for (j = 0; j < count; j++, pos++) {
3380 blksize = cdata->expect.blksize;
3381 kl = 0;
3382
3383
3384
3385
3386
3387 if ((cdata->expect.intensity & 0x08) &&
3388 geo.cyl == 0 && geo.head == 0) {
3389 if (j < 3) {
3390 blksize = sizes_trk0[j] - 4;
3391 kl = 4;
3392 }
3393 }
3394 if ((cdata->expect.intensity & 0x08) &&
3395 geo.cyl == 0 && geo.head == 1) {
3396 blksize = LABEL_SIZE - 44;
3397 kl = 44;
3398 }
3399
3400
3401 if (fmt_buffer[pos].dl != blksize) {
3402 cdata->result = DASD_FMT_ERR_BLKSIZE;
3403 goto out;
3404 }
3405
3406 if (fmt_buffer[pos].kl != kl) {
3407 cdata->result = DASD_FMT_ERR_KEY_LENGTH;
3408 goto out;
3409 }
3410
3411 if (fmt_buffer[pos].cyl != geo.cyl ||
3412 fmt_buffer[pos].head != geo.head ||
3413 fmt_buffer[pos].record != (j + 1)) {
3414 cdata->result = DASD_FMT_ERR_RECORD_ID;
3415 goto out;
3416 }
3417 }
3418 }
3419
3420out:
3421
3422
3423
3424
3425 if (!cdata->result) {
3426 i--;
3427 pos--;
3428 }
3429
3430 cdata->unit = i;
3431 cdata->num_records = count;
3432 cdata->rec = fmt_buffer[pos].record;
3433 cdata->blksize = fmt_buffer[pos].dl;
3434 cdata->key_length = fmt_buffer[pos].kl;
3435}
3436
3437
3438
3439
3440static int dasd_eckd_check_device_format(struct dasd_device *base,
3441 struct format_check_t *cdata,
3442 int enable_pav)
3443{
3444 struct dasd_eckd_private *private = base->private;
3445 struct eckd_count *fmt_buffer;
3446 struct irb irb;
3447 int rpt_max, rpt_exp;
3448 int fmt_buffer_size;
3449 int trk_per_cyl;
3450 int trkcount;
3451 int tpm = 0;
3452 int rc;
3453
3454 trk_per_cyl = private->rdc_data.trk_per_cyl;
3455
3456
3457 rpt_max = recs_per_track(&private->rdc_data, 0, 512) + 1;
3458 rpt_exp = recs_per_track(&private->rdc_data, 0, cdata->expect.blksize);
3459
3460 trkcount = cdata->expect.stop_unit - cdata->expect.start_unit + 1;
3461 fmt_buffer_size = trkcount * rpt_max * sizeof(struct eckd_count);
3462
3463 fmt_buffer = kzalloc(fmt_buffer_size, GFP_KERNEL | GFP_DMA);
3464 if (!fmt_buffer)
3465 return -ENOMEM;
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475 if ((private->features.feature[40] & 0x04) &&
3476 fmt_buffer_size <= private->fcx_max_data)
3477 tpm = 1;
3478
3479 rc = dasd_eckd_format_process_data(base, &cdata->expect, enable_pav,
3480 tpm, fmt_buffer, rpt_max, &irb);
3481 if (rc && rc != -EIO)
3482 goto out;
3483 if (rc == -EIO) {
3484
3485
3486
3487
3488
3489 if (tpm && scsw_cstat(&irb.scsw) == 0x40) {
3490 tpm = 0;
3491 rc = dasd_eckd_format_process_data(base, &cdata->expect,
3492 enable_pav, tpm,
3493 fmt_buffer, rpt_max,
3494 &irb);
3495 if (rc)
3496 goto out;
3497 } else {
3498 goto out;
3499 }
3500 }
3501
3502 dasd_eckd_format_evaluate_tracks(fmt_buffer, cdata, rpt_max, rpt_exp,
3503 trk_per_cyl, tpm);
3504
3505out:
3506 kfree(fmt_buffer);
3507
3508 return rc;
3509}
3510
3511static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)
3512{
3513 if (cqr->retries < 0) {
3514 cqr->status = DASD_CQR_FAILED;
3515 return;
3516 }
3517 cqr->status = DASD_CQR_FILLED;
3518 if (cqr->block && (cqr->startdev != cqr->block->base)) {
3519 dasd_eckd_reset_ccw_to_base_io(cqr);
3520 cqr->startdev = cqr->block->base;
3521 cqr->lpm = dasd_path_get_opm(cqr->block->base);
3522 }
3523};
3524
3525static dasd_erp_fn_t
3526dasd_eckd_erp_action(struct dasd_ccw_req * cqr)
3527{
3528 struct dasd_device *device = (struct dasd_device *) cqr->startdev;
3529 struct ccw_device *cdev = device->cdev;
3530
3531 switch (cdev->id.cu_type) {
3532 case 0x3990:
3533 case 0x2105:
3534 case 0x2107:
3535 case 0x1750:
3536 return dasd_3990_erp_action;
3537 case 0x9343:
3538 case 0x3880:
3539 default:
3540 return dasd_default_erp_action;
3541 }
3542}
3543
3544static dasd_erp_fn_t
3545dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr)
3546{
3547 return dasd_default_erp_postaction;
3548}
3549
3550static void dasd_eckd_check_for_device_change(struct dasd_device *device,
3551 struct dasd_ccw_req *cqr,
3552 struct irb *irb)
3553{
3554 char mask;
3555 char *sense = NULL;
3556 struct dasd_eckd_private *private = device->private;
3557
3558
3559 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
3560 if ((scsw_dstat(&irb->scsw) & mask) == mask) {
3561
3562
3563
3564
3565 if (!device->block && private->lcu &&
3566 device->state == DASD_STATE_ONLINE &&
3567 !test_bit(DASD_FLAG_OFFLINE, &device->flags) &&
3568 !test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
3569
3570 dasd_reload_device(device);
3571 }
3572 dasd_generic_handle_state_change(device);
3573 return;
3574 }
3575
3576 sense = dasd_get_sense(irb);
3577 if (!sense)
3578 return;
3579
3580
3581 if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) &&
3582 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) {
3583 if (test_and_set_bit(DASD_FLAG_SUC, &device->flags)) {
3584 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
3585 "eckd suc: device already notified");
3586 return;
3587 }
3588 sense = dasd_get_sense(irb);
3589 if (!sense) {
3590 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
3591 "eckd suc: no reason code available");
3592 clear_bit(DASD_FLAG_SUC, &device->flags);
3593 return;
3594
3595 }
3596 private->suc_reason = sense[8];
3597 DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
3598 "eckd handle summary unit check: reason",
3599 private->suc_reason);
3600 dasd_get_device(device);
3601 if (!schedule_work(&device->suc_work))
3602 dasd_put_device(device);
3603
3604 return;
3605 }
3606
3607
3608 if (!cqr && !(sense[27] & DASD_SENSE_BIT_0) &&
3609 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
3610 dasd_3990_erp_handle_sim(device, sense);
3611 return;
3612 }
3613
3614
3615
3616
3617 if (device->block && (sense[27] & DASD_SENSE_BIT_0) &&
3618 (sense[7] == 0x3F) &&
3619 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
3620 test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) {
3621 if (device->features & DASD_FEATURE_FAILONSLCK)
3622 set_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
3623 clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);
3624 dev_err(&device->cdev->dev,
3625 "The device reservation was lost\n");
3626 }
3627}
3628
3629static int dasd_eckd_ras_sanity_checks(struct dasd_device *device,
3630 unsigned int first_trk,
3631 unsigned int last_trk)
3632{
3633 struct dasd_eckd_private *private = device->private;
3634 unsigned int trks_per_vol;
3635 int rc = 0;
3636
3637 trks_per_vol = private->real_cyl * private->rdc_data.trk_per_cyl;
3638
3639 if (first_trk >= trks_per_vol) {
3640 dev_warn(&device->cdev->dev,
3641 "Start track number %u used in the space release command is too big\n",
3642 first_trk);
3643 rc = -EINVAL;
3644 } else if (last_trk >= trks_per_vol) {
3645 dev_warn(&device->cdev->dev,
3646 "Stop track number %u used in the space release command is too big\n",
3647 last_trk);
3648 rc = -EINVAL;
3649 } else if (first_trk > last_trk) {
3650 dev_warn(&device->cdev->dev,
3651 "Start track %u used in the space release command exceeds the end track\n",
3652 first_trk);
3653 rc = -EINVAL;
3654 }
3655 return rc;
3656}
3657
3658
3659
3660
3661
3662static int count_exts(unsigned int from, unsigned int to, int trks_per_ext)
3663{
3664 int cur_pos = 0;
3665 int count = 0;
3666 int tmp;
3667
3668 if (from == to)
3669 return 1;
3670
3671
3672 if (from % trks_per_ext != 0) {
3673 tmp = from + trks_per_ext - (from % trks_per_ext) - 1;
3674 if (tmp > to)
3675 tmp = to;
3676 cur_pos = tmp - from + 1;
3677 count++;
3678 }
3679
3680 if (to - (from + cur_pos) + 1 >= trks_per_ext) {
3681 tmp = to - ((to - trks_per_ext + 1) % trks_per_ext);
3682 count += (tmp - (from + cur_pos) + 1) / trks_per_ext;
3683 cur_pos = tmp;
3684 }
3685
3686 if (cur_pos < to)
3687 count++;
3688
3689 return count;
3690}
3691
3692
3693
3694
3695static struct dasd_ccw_req *
3696dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
3697 struct request *req, unsigned int first_trk,
3698 unsigned int last_trk, int by_extent)
3699{
3700 struct dasd_eckd_private *private = device->private;
3701 struct dasd_dso_ras_ext_range *ras_range;
3702 struct dasd_rssd_features *features;
3703 struct dasd_dso_ras_data *ras_data;
3704 u16 heads, beg_head, end_head;
3705 int cur_to_trk, cur_from_trk;
3706 struct dasd_ccw_req *cqr;
3707 u32 beg_cyl, end_cyl;
3708 struct ccw1 *ccw;
3709 int trks_per_ext;
3710 size_t ras_size;
3711 size_t size;
3712 int nr_exts;
3713 void *rq;
3714 int i;
3715
3716 if (dasd_eckd_ras_sanity_checks(device, first_trk, last_trk))
3717 return ERR_PTR(-EINVAL);
3718
3719 rq = req ? blk_mq_rq_to_pdu(req) : NULL;
3720
3721 features = &private->features;
3722
3723 trks_per_ext = dasd_eckd_ext_size(device) * private->rdc_data.trk_per_cyl;
3724 nr_exts = 0;
3725 if (by_extent)
3726 nr_exts = count_exts(first_trk, last_trk, trks_per_ext);
3727 ras_size = sizeof(*ras_data);
3728 size = ras_size + (nr_exts * sizeof(*ras_range));
3729
3730 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, size, device, rq);
3731 if (IS_ERR(cqr)) {
3732 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
3733 "Could not allocate RAS request");
3734 return cqr;
3735 }
3736
3737 ras_data = cqr->data;
3738 memset(ras_data, 0, size);
3739
3740 ras_data->order = DSO_ORDER_RAS;
3741 ras_data->flags.vol_type = 0;
3742
3743 ras_data->op_flags.by_extent = by_extent;
3744
3745
3746
3747
3748
3749 ras_data->op_flags.guarantee_init = !!(features->feature[56] & 0x01);
3750 ras_data->lss = private->ned->ID;
3751 ras_data->dev_addr = private->ned->unit_addr;
3752 ras_data->nr_exts = nr_exts;
3753
3754 if (by_extent) {
3755 heads = private->rdc_data.trk_per_cyl;
3756 cur_from_trk = first_trk;
3757 cur_to_trk = first_trk + trks_per_ext -
3758 (first_trk % trks_per_ext) - 1;
3759 if (cur_to_trk > last_trk)
3760 cur_to_trk = last_trk;
3761 ras_range = (struct dasd_dso_ras_ext_range *)(cqr->data + ras_size);
3762
3763 for (i = 0; i < nr_exts; i++) {
3764 beg_cyl = cur_from_trk / heads;
3765 beg_head = cur_from_trk % heads;
3766 end_cyl = cur_to_trk / heads;
3767 end_head = cur_to_trk % heads;
3768
3769 set_ch_t(&ras_range->beg_ext, beg_cyl, beg_head);
3770 set_ch_t(&ras_range->end_ext, end_cyl, end_head);
3771
3772 cur_from_trk = cur_to_trk + 1;
3773 cur_to_trk = cur_from_trk + trks_per_ext - 1;
3774 if (cur_to_trk > last_trk)
3775 cur_to_trk = last_trk;
3776 ras_range++;
3777 }
3778 }
3779
3780 ccw = cqr->cpaddr;
3781 ccw->cda = (__u32)(addr_t)cqr->data;
3782 ccw->cmd_code = DASD_ECKD_CCW_DSO;
3783 ccw->count = size;
3784
3785 cqr->startdev = device;
3786 cqr->memdev = device;
3787 cqr->block = block;
3788 cqr->retries = 256;
3789 cqr->expires = device->default_expires * HZ;
3790 cqr->buildclk = get_tod_clock();
3791 cqr->status = DASD_CQR_FILLED;
3792
3793 return cqr;
3794}
3795
3796static int dasd_eckd_release_space_full(struct dasd_device *device)
3797{
3798 struct dasd_ccw_req *cqr;
3799 int rc;
3800
3801 cqr = dasd_eckd_dso_ras(device, NULL, NULL, 0, 0, 0);
3802 if (IS_ERR(cqr))
3803 return PTR_ERR(cqr);
3804
3805 rc = dasd_sleep_on_interruptible(cqr);
3806
3807 dasd_sfree_request(cqr, cqr->memdev);
3808
3809 return rc;
3810}
3811
3812static int dasd_eckd_release_space_trks(struct dasd_device *device,
3813 unsigned int from, unsigned int to)
3814{
3815 struct dasd_eckd_private *private = device->private;
3816 struct dasd_block *block = device->block;
3817 struct dasd_ccw_req *cqr, *n;
3818 struct list_head ras_queue;
3819 unsigned int device_exts;
3820 int trks_per_ext;
3821 int stop, step;
3822 int cur_pos;
3823 int rc = 0;
3824 int retry;
3825
3826 INIT_LIST_HEAD(&ras_queue);
3827
3828 device_exts = private->real_cyl / dasd_eckd_ext_size(device);
3829 trks_per_ext = dasd_eckd_ext_size(device) * private->rdc_data.trk_per_cyl;
3830
3831
3832 step = trks_per_ext * min(device_exts, DASD_ECKD_RAS_EXTS_MAX);
3833 cur_pos = from;
3834
3835 do {
3836 retry = 0;
3837 while (cur_pos < to) {
3838 stop = cur_pos + step -
3839 ((cur_pos + step) % trks_per_ext) - 1;
3840 if (stop > to)
3841 stop = to;
3842
3843 cqr = dasd_eckd_dso_ras(device, NULL, NULL, cur_pos, stop, 1);
3844 if (IS_ERR(cqr)) {
3845 rc = PTR_ERR(cqr);
3846 if (rc == -ENOMEM) {
3847 if (list_empty(&ras_queue))
3848 goto out;
3849 retry = 1;
3850 break;
3851 }
3852 goto err_out;
3853 }
3854
3855 spin_lock_irq(&block->queue_lock);
3856 list_add_tail(&cqr->blocklist, &ras_queue);
3857 spin_unlock_irq(&block->queue_lock);
3858 cur_pos = stop + 1;
3859 }
3860
3861 rc = dasd_sleep_on_queue_interruptible(&ras_queue);
3862
3863err_out:
3864 list_for_each_entry_safe(cqr, n, &ras_queue, blocklist) {
3865 device = cqr->startdev;
3866 private = device->private;
3867
3868 spin_lock_irq(&block->queue_lock);
3869 list_del_init(&cqr->blocklist);
3870 spin_unlock_irq(&block->queue_lock);
3871 dasd_sfree_request(cqr, device);
3872 private->count--;
3873 }
3874 } while (retry);
3875
3876out:
3877 return rc;
3878}
3879
3880static int dasd_eckd_release_space(struct dasd_device *device,
3881 struct format_data_t *rdata)
3882{
3883 if (rdata->intensity & DASD_FMT_INT_ESE_FULL)
3884 return dasd_eckd_release_space_full(device);
3885 else if (rdata->intensity == 0)
3886 return dasd_eckd_release_space_trks(device, rdata->start_unit,
3887 rdata->stop_unit);
3888 else
3889 return -EINVAL;
3890}
3891
3892static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
3893 struct dasd_device *startdev,
3894 struct dasd_block *block,
3895 struct request *req,
3896 sector_t first_rec,
3897 sector_t last_rec,
3898 sector_t first_trk,
3899 sector_t last_trk,
3900 unsigned int first_offs,
3901 unsigned int last_offs,
3902 unsigned int blk_per_trk,
3903 unsigned int blksize)
3904{
3905 struct dasd_eckd_private *private;
3906 unsigned long *idaws;
3907 struct LO_eckd_data *LO_data;
3908 struct dasd_ccw_req *cqr;
3909 struct ccw1 *ccw;
3910 struct req_iterator iter;
3911 struct bio_vec bv;
3912 char *dst;
3913 unsigned int off;
3914 int count, cidaw, cplength, datasize;
3915 sector_t recid;
3916 unsigned char cmd, rcmd;
3917 int use_prefix;
3918 struct dasd_device *basedev;
3919
3920 basedev = block->base;
3921 private = basedev->private;
3922 if (rq_data_dir(req) == READ)
3923 cmd = DASD_ECKD_CCW_READ_MT;
3924 else if (rq_data_dir(req) == WRITE)
3925 cmd = DASD_ECKD_CCW_WRITE_MT;
3926 else
3927 return ERR_PTR(-EINVAL);
3928
3929
3930 count = 0;
3931 cidaw = 0;
3932 rq_for_each_segment(bv, req, iter) {
3933 if (bv.bv_len & (blksize - 1))
3934
3935 return ERR_PTR(-EINVAL);
3936 count += bv.bv_len >> (block->s2b_shift + 9);
3937 if (idal_is_needed (page_address(bv.bv_page), bv.bv_len))
3938 cidaw += bv.bv_len >> (block->s2b_shift + 9);
3939 }
3940
3941 if (count != last_rec - first_rec + 1)
3942 return ERR_PTR(-EINVAL);
3943
3944
3945 use_prefix = private->features.feature[8] & 0x01;
3946 if (use_prefix) {
3947
3948 cplength = 2 + count;
3949
3950 datasize = sizeof(struct PFX_eckd_data) +
3951 sizeof(struct LO_eckd_data) +
3952 cidaw * sizeof(unsigned long);
3953 } else {
3954
3955 cplength = 2 + count;
3956
3957 datasize = sizeof(struct DE_eckd_data) +
3958 sizeof(struct LO_eckd_data) +
3959 cidaw * sizeof(unsigned long);
3960 }
3961
3962 if (private->uses_cdl && first_rec < 2*blk_per_trk) {
3963 if (last_rec >= 2*blk_per_trk)
3964 count = 2*blk_per_trk - first_rec;
3965 cplength += count;
3966 datasize += count*sizeof(struct LO_eckd_data);
3967 }
3968
3969 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize,
3970 startdev, blk_mq_rq_to_pdu(req));
3971 if (IS_ERR(cqr))
3972 return cqr;
3973 ccw = cqr->cpaddr;
3974
3975 if (use_prefix) {
3976 if (prefix(ccw++, cqr->data, first_trk,
3977 last_trk, cmd, basedev, startdev) == -EAGAIN) {
3978
3979
3980
3981 dasd_sfree_request(cqr, startdev);
3982 return ERR_PTR(-EAGAIN);
3983 }
3984 idaws = (unsigned long *) (cqr->data +
3985 sizeof(struct PFX_eckd_data));
3986 } else {
3987 if (define_extent(ccw++, cqr->data, first_trk,
3988 last_trk, cmd, basedev, 0) == -EAGAIN) {
3989
3990
3991
3992 dasd_sfree_request(cqr, startdev);
3993 return ERR_PTR(-EAGAIN);
3994 }
3995 idaws = (unsigned long *) (cqr->data +
3996 sizeof(struct DE_eckd_data));
3997 }
3998
3999 LO_data = (struct LO_eckd_data *) (idaws + cidaw);
4000 recid = first_rec;
4001 if (private->uses_cdl == 0 || recid > 2*blk_per_trk) {
4002
4003 ccw[-1].flags |= CCW_FLAG_CC;
4004 locate_record(ccw++, LO_data++, first_trk, first_offs + 1,
4005 last_rec - recid + 1, cmd, basedev, blksize);
4006 }
4007 rq_for_each_segment(bv, req, iter) {
4008 dst = page_address(bv.bv_page) + bv.bv_offset;
4009 if (dasd_page_cache) {
4010 char *copy = kmem_cache_alloc(dasd_page_cache,
4011 GFP_DMA | __GFP_NOWARN);
4012 if (copy && rq_data_dir(req) == WRITE)
4013 memcpy(copy + bv.bv_offset, dst, bv.bv_len);
4014 if (copy)
4015 dst = copy + bv.bv_offset;
4016 }
4017 for (off = 0; off < bv.bv_len; off += blksize) {
4018 sector_t trkid = recid;
4019 unsigned int recoffs = sector_div(trkid, blk_per_trk);
4020 rcmd = cmd;
4021 count = blksize;
4022
4023 if (private->uses_cdl && recid < 2*blk_per_trk) {
4024 if (dasd_eckd_cdl_special(blk_per_trk, recid)){
4025 rcmd |= 0x8;
4026 count = dasd_eckd_cdl_reclen(recid);
4027 if (count < blksize &&
4028 rq_data_dir(req) == READ)
4029 memset(dst + count, 0xe5,
4030 blksize - count);
4031 }
4032 ccw[-1].flags |= CCW_FLAG_CC;
4033 locate_record(ccw++, LO_data++,
4034 trkid, recoffs + 1,
4035 1, rcmd, basedev, count);
4036 }
4037
4038 if (private->uses_cdl && recid == 2*blk_per_trk) {
4039 ccw[-1].flags |= CCW_FLAG_CC;
4040 locate_record(ccw++, LO_data++,
4041 trkid, recoffs + 1,
4042 last_rec - recid + 1,
4043 cmd, basedev, count);
4044 }
4045
4046 ccw[-1].flags |= CCW_FLAG_CC;
4047 ccw->cmd_code = rcmd;
4048 ccw->count = count;
4049 if (idal_is_needed(dst, blksize)) {
4050 ccw->cda = (__u32)(addr_t) idaws;
4051 ccw->flags = CCW_FLAG_IDA;
4052 idaws = idal_create_words(idaws, dst, blksize);
4053 } else {
4054 ccw->cda = (__u32)(addr_t) dst;
4055 ccw->flags = 0;
4056 }
4057 ccw++;
4058 dst += blksize;
4059 recid++;
4060 }
4061 }
4062 if (blk_noretry_request(req) ||
4063 block->base->features & DASD_FEATURE_FAILFAST)
4064 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
4065 cqr->startdev = startdev;
4066 cqr->memdev = startdev;
4067 cqr->block = block;
4068 cqr->expires = startdev->default_expires * HZ;
4069 cqr->lpm = dasd_path_get_ppm(startdev);
4070 cqr->retries = startdev->default_retries;
4071 cqr->buildclk = get_tod_clock();
4072 cqr->status = DASD_CQR_FILLED;
4073
4074
4075 if (dasd_eckd_is_ese(basedev)) {
4076 set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
4077 set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
4078 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
4079 }
4080
4081 return cqr;
4082}
4083
4084static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
4085 struct dasd_device *startdev,
4086 struct dasd_block *block,
4087 struct request *req,
4088 sector_t first_rec,
4089 sector_t last_rec,
4090 sector_t first_trk,
4091 sector_t last_trk,
4092 unsigned int first_offs,
4093 unsigned int last_offs,
4094 unsigned int blk_per_trk,
4095 unsigned int blksize)
4096{
4097 unsigned long *idaws;
4098 struct dasd_ccw_req *cqr;
4099 struct ccw1 *ccw;
4100 struct req_iterator iter;
4101 struct bio_vec bv;
4102 char *dst, *idaw_dst;
4103 unsigned int cidaw, cplength, datasize;
4104 unsigned int tlf;
4105 sector_t recid;
4106 unsigned char cmd;
4107 struct dasd_device *basedev;
4108 unsigned int trkcount, count, count_to_trk_end;
4109 unsigned int idaw_len, seg_len, part_len, len_to_track_end;
4110 unsigned char new_track, end_idaw;
4111 sector_t trkid;
4112 unsigned int recoffs;
4113
4114 basedev = block->base;
4115 if (rq_data_dir(req) == READ)
4116 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
4117 else if (rq_data_dir(req) == WRITE)
4118 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
4119 else
4120 return ERR_PTR(-EINVAL);
4121
4122
4123
4124
4125
4126
4127 cidaw = last_rec - first_rec + 1;
4128 trkcount = last_trk - first_trk + 1;
4129
4130
4131 cplength = 1 + trkcount;
4132
4133 datasize = sizeof(struct PFX_eckd_data) + cidaw * sizeof(unsigned long);
4134
4135
4136 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize,
4137 startdev, blk_mq_rq_to_pdu(req));
4138 if (IS_ERR(cqr))
4139 return cqr;
4140 ccw = cqr->cpaddr;
4141
4142 if (first_trk == last_trk)
4143 tlf = last_offs - first_offs + 1;
4144 else
4145 tlf = last_offs + 1;
4146 tlf *= blksize;
4147
4148 if (prefix_LRE(ccw++, cqr->data, first_trk,
4149 last_trk, cmd, basedev, startdev,
4150 1 , first_offs + 1,
4151 trkcount, blksize,
4152 tlf) == -EAGAIN) {
4153
4154
4155
4156 dasd_sfree_request(cqr, startdev);
4157 return ERR_PTR(-EAGAIN);
4158 }
4159
4160
4161
4162
4163
4164
4165
4166
4167 idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
4168 recid = first_rec;
4169 new_track = 1;
4170 end_idaw = 0;
4171 len_to_track_end = 0;
4172 idaw_dst = NULL;
4173 idaw_len = 0;
4174 rq_for_each_segment(bv, req, iter) {
4175 dst = page_address(bv.bv_page) + bv.bv_offset;
4176 seg_len = bv.bv_len;
4177 while (seg_len) {
4178 if (new_track) {
4179 trkid = recid;
4180 recoffs = sector_div(trkid, blk_per_trk);
4181 count_to_trk_end = blk_per_trk - recoffs;
4182 count = min((last_rec - recid + 1),
4183 (sector_t)count_to_trk_end);
4184 len_to_track_end = count * blksize;
4185 ccw[-1].flags |= CCW_FLAG_CC;
4186 ccw->cmd_code = cmd;
4187 ccw->count = len_to_track_end;
4188 ccw->cda = (__u32)(addr_t)idaws;
4189 ccw->flags = CCW_FLAG_IDA;
4190 ccw++;
4191 recid += count;
4192 new_track = 0;
4193
4194 if (!idaw_dst)
4195 idaw_dst = dst;
4196 }
4197
4198
4199
4200
4201
4202
4203 if (!idaw_dst) {
4204 if (__pa(dst) & (IDA_BLOCK_SIZE-1)) {
4205 dasd_sfree_request(cqr, startdev);
4206 return ERR_PTR(-ERANGE);
4207 } else
4208 idaw_dst = dst;
4209 }
4210 if ((idaw_dst + idaw_len) != dst) {
4211 dasd_sfree_request(cqr, startdev);
4212 return ERR_PTR(-ERANGE);
4213 }
4214 part_len = min(seg_len, len_to_track_end);
4215 seg_len -= part_len;
4216 dst += part_len;
4217 idaw_len += part_len;
4218 len_to_track_end -= part_len;
4219
4220
4221
4222
4223
4224 if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
4225 end_idaw = 1;
4226
4227 if (!len_to_track_end) {
4228 new_track = 1;
4229 end_idaw = 1;
4230 }
4231 if (end_idaw) {
4232 idaws = idal_create_words(idaws, idaw_dst,
4233 idaw_len);
4234 idaw_dst = NULL;
4235 idaw_len = 0;
4236 end_idaw = 0;
4237 }
4238 }
4239 }
4240
4241 if (blk_noretry_request(req) ||
4242 block->base->features & DASD_FEATURE_FAILFAST)
4243 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
4244 cqr->startdev = startdev;
4245 cqr->memdev = startdev;
4246 cqr->block = block;
4247 cqr->expires = startdev->default_expires * HZ;
4248 cqr->lpm = dasd_path_get_ppm(startdev);
4249 cqr->retries = startdev->default_retries;
4250 cqr->buildclk = get_tod_clock();
4251 cqr->status = DASD_CQR_FILLED;
4252
4253
4254 if (dasd_eckd_is_ese(basedev))
4255 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
4256
4257 return cqr;
4258}
4259
4260static int prepare_itcw(struct itcw *itcw,
4261 unsigned int trk, unsigned int totrk, int cmd,
4262 struct dasd_device *basedev,
4263 struct dasd_device *startdev,
4264 unsigned int rec_on_trk, int count,
4265 unsigned int blksize,
4266 unsigned int total_data_size,
4267 unsigned int tlf,
4268 unsigned int blk_per_trk)
4269{
4270 struct PFX_eckd_data pfxdata;
4271 struct dasd_eckd_private *basepriv, *startpriv;
4272 struct DE_eckd_data *dedata;
4273 struct LRE_eckd_data *lredata;
4274 struct dcw *dcw;
4275
4276 u32 begcyl, endcyl;
4277 u16 heads, beghead, endhead;
4278 u8 pfx_cmd;
4279
4280 int rc = 0;
4281 int sector = 0;
4282 int dn, d;
4283
4284
4285
4286 basepriv = basedev->private;
4287 startpriv = startdev->private;
4288 dedata = &pfxdata.define_extent;
4289 lredata = &pfxdata.locate_record;
4290
4291 memset(&pfxdata, 0, sizeof(pfxdata));
4292 pfxdata.format = 1;
4293 pfxdata.base_address = basepriv->ned->unit_addr;
4294 pfxdata.base_lss = basepriv->ned->ID;
4295 pfxdata.validity.define_extent = 1;
4296
4297
4298 if (startpriv->uid.type == UA_BASE_PAV_ALIAS)
4299 pfxdata.validity.verify_base = 1;
4300
4301 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS) {
4302 pfxdata.validity.verify_base = 1;
4303 pfxdata.validity.hyper_pav = 1;
4304 }
4305
4306 switch (cmd) {
4307 case DASD_ECKD_CCW_READ_TRACK_DATA:
4308 dedata->mask.perm = 0x1;
4309 dedata->attributes.operation = basepriv->attrib.operation;
4310 dedata->blk_size = blksize;
4311 dedata->ga_extended |= 0x42;
4312 lredata->operation.orientation = 0x0;
4313 lredata->operation.operation = 0x0C;
4314 lredata->auxiliary.check_bytes = 0x01;
4315 pfx_cmd = DASD_ECKD_CCW_PFX_READ;
4316 break;
4317 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
4318 dedata->mask.perm = 0x02;
4319 dedata->attributes.operation = basepriv->attrib.operation;
4320 dedata->blk_size = blksize;
4321 rc = set_timestamp(NULL, dedata, basedev);
4322 dedata->ga_extended |= 0x42;
4323 lredata->operation.orientation = 0x0;
4324 lredata->operation.operation = 0x3F;
4325 lredata->extended_operation = 0x23;
4326 lredata->auxiliary.check_bytes = 0x2;
4327
4328
4329
4330
4331
4332 if (dedata->ga_extended & 0x08 && dedata->ga_extended & 0x02)
4333 pfxdata.validity.time_stamp = 1;
4334 pfx_cmd = DASD_ECKD_CCW_PFX;
4335 break;
4336 case DASD_ECKD_CCW_READ_COUNT_MT:
4337 dedata->mask.perm = 0x1;
4338 dedata->attributes.operation = DASD_BYPASS_CACHE;
4339 dedata->ga_extended |= 0x42;
4340 dedata->blk_size = blksize;
4341 lredata->operation.orientation = 0x2;
4342 lredata->operation.operation = 0x16;
4343 lredata->auxiliary.check_bytes = 0x01;
4344 pfx_cmd = DASD_ECKD_CCW_PFX_READ;
4345 break;
4346 default:
4347 DBF_DEV_EVENT(DBF_ERR, basedev,
4348 "prepare itcw, unknown opcode 0x%x", cmd);
4349 BUG();
4350 break;
4351 }
4352 if (rc)
4353 return rc;
4354
4355 dedata->attributes.mode = 0x3;
4356
4357 heads = basepriv->rdc_data.trk_per_cyl;
4358 begcyl = trk / heads;
4359 beghead = trk % heads;
4360 endcyl = totrk / heads;
4361 endhead = totrk % heads;
4362
4363
4364 if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
4365 dedata->attributes.operation == DASD_SEQ_ACCESS) {
4366
4367 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
4368 endcyl += basepriv->attrib.nr_cyl;
4369 else
4370 endcyl = (basepriv->real_cyl - 1);
4371 }
4372
4373 set_ch_t(&dedata->beg_ext, begcyl, beghead);
4374 set_ch_t(&dedata->end_ext, endcyl, endhead);
4375
4376 dedata->ep_format = 0x20;
4377 dedata->ep_rec_per_track = blk_per_trk;
4378
4379 if (rec_on_trk) {
4380 switch (basepriv->rdc_data.dev_type) {
4381 case 0x3390:
4382 dn = ceil_quot(blksize + 6, 232);
4383 d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
4384 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
4385 break;
4386 case 0x3380:
4387 d = 7 + ceil_quot(blksize + 12, 32);
4388 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
4389 break;
4390 }
4391 }
4392
4393 if (cmd == DASD_ECKD_CCW_READ_COUNT_MT) {
4394 lredata->auxiliary.length_valid = 0;
4395 lredata->auxiliary.length_scope = 0;
4396 lredata->sector = 0xff;
4397 } else {
4398 lredata->auxiliary.length_valid = 1;
4399 lredata->auxiliary.length_scope = 1;
4400 lredata->sector = sector;
4401 }
4402 lredata->auxiliary.imbedded_ccw_valid = 1;
4403 lredata->length = tlf;
4404 lredata->imbedded_ccw = cmd;
4405 lredata->count = count;
4406 set_ch_t(&lredata->seek_addr, begcyl, beghead);
4407 lredata->search_arg.cyl = lredata->seek_addr.cyl;
4408 lredata->search_arg.head = lredata->seek_addr.head;
4409 lredata->search_arg.record = rec_on_trk;
4410
4411 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
4412 &pfxdata, sizeof(pfxdata), total_data_size);
4413 return PTR_RET(dcw);
4414}
4415
4416static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
4417 struct dasd_device *startdev,
4418 struct dasd_block *block,
4419 struct request *req,
4420 sector_t first_rec,
4421 sector_t last_rec,
4422 sector_t first_trk,
4423 sector_t last_trk,
4424 unsigned int first_offs,
4425 unsigned int last_offs,
4426 unsigned int blk_per_trk,
4427 unsigned int blksize)
4428{
4429 struct dasd_ccw_req *cqr;
4430 struct req_iterator iter;
4431 struct bio_vec bv;
4432 char *dst;
4433 unsigned int trkcount, ctidaw;
4434 unsigned char cmd;
4435 struct dasd_device *basedev;
4436 unsigned int tlf;
4437 struct itcw *itcw;
4438 struct tidaw *last_tidaw = NULL;
4439 int itcw_op;
4440 size_t itcw_size;
4441 u8 tidaw_flags;
4442 unsigned int seg_len, part_len, len_to_track_end;
4443 unsigned char new_track;
4444 sector_t recid, trkid;
4445 unsigned int offs;
4446 unsigned int count, count_to_trk_end;
4447 int ret;
4448
4449 basedev = block->base;
4450 if (rq_data_dir(req) == READ) {
4451 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
4452 itcw_op = ITCW_OP_READ;
4453 } else if (rq_data_dir(req) == WRITE) {
4454 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
4455 itcw_op = ITCW_OP_WRITE;
4456 } else
4457 return ERR_PTR(-EINVAL);
4458
4459
4460
4461
4462
4463
4464
4465 trkcount = last_trk - first_trk + 1;
4466 ctidaw = 0;
4467 rq_for_each_segment(bv, req, iter) {
4468 ++ctidaw;
4469 }
4470 if (rq_data_dir(req) == WRITE)
4471 ctidaw += (last_trk - first_trk);
4472
4473
4474 itcw_size = itcw_calc_size(0, ctidaw, 0);
4475 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 0, itcw_size, startdev,
4476 blk_mq_rq_to_pdu(req));
4477 if (IS_ERR(cqr))
4478 return cqr;
4479
4480
4481 if (first_trk == last_trk)
4482 tlf = last_offs - first_offs + 1;
4483 else
4484 tlf = last_offs + 1;
4485 tlf *= blksize;
4486
4487 itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
4488 if (IS_ERR(itcw)) {
4489 ret = -EINVAL;
4490 goto out_error;
4491 }
4492 cqr->cpaddr = itcw_get_tcw(itcw);
4493 if (prepare_itcw(itcw, first_trk, last_trk,
4494 cmd, basedev, startdev,
4495 first_offs + 1,
4496 trkcount, blksize,
4497 (last_rec - first_rec + 1) * blksize,
4498 tlf, blk_per_trk) == -EAGAIN) {
4499
4500
4501
4502 ret = -EAGAIN;
4503 goto out_error;
4504 }
4505 len_to_track_end = 0;
4506
4507
4508
4509
4510
4511
4512
4513
4514 if (rq_data_dir(req) == WRITE) {
4515 new_track = 1;
4516 recid = first_rec;
4517 rq_for_each_segment(bv, req, iter) {
4518 dst = page_address(bv.bv_page) + bv.bv_offset;
4519 seg_len = bv.bv_len;
4520 while (seg_len) {
4521 if (new_track) {
4522 trkid = recid;
4523 offs = sector_div(trkid, blk_per_trk);
4524 count_to_trk_end = blk_per_trk - offs;
4525 count = min((last_rec - recid + 1),
4526 (sector_t)count_to_trk_end);
4527 len_to_track_end = count * blksize;
4528 recid += count;
4529 new_track = 0;
4530 }
4531 part_len = min(seg_len, len_to_track_end);
4532 seg_len -= part_len;
4533 len_to_track_end -= part_len;
4534
4535 if (!len_to_track_end) {
4536 new_track = 1;
4537 tidaw_flags = TIDAW_FLAGS_INSERT_CBC;
4538 } else
4539 tidaw_flags = 0;
4540 last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
4541 dst, part_len);
4542 if (IS_ERR(last_tidaw)) {
4543 ret = -EINVAL;
4544 goto out_error;
4545 }
4546 dst += part_len;
4547 }
4548 }
4549 } else {
4550 rq_for_each_segment(bv, req, iter) {
4551 dst = page_address(bv.bv_page) + bv.bv_offset;
4552 last_tidaw = itcw_add_tidaw(itcw, 0x00,
4553 dst, bv.bv_len);
4554 if (IS_ERR(last_tidaw)) {
4555 ret = -EINVAL;
4556 goto out_error;
4557 }
4558 }
4559 }
4560 last_tidaw->flags |= TIDAW_FLAGS_LAST;
4561 last_tidaw->flags &= ~TIDAW_FLAGS_INSERT_CBC;
4562 itcw_finalize(itcw);
4563
4564 if (blk_noretry_request(req) ||
4565 block->base->features & DASD_FEATURE_FAILFAST)
4566 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
4567 cqr->cpmode = 1;
4568 cqr->startdev = startdev;
4569 cqr->memdev = startdev;
4570 cqr->block = block;
4571 cqr->expires = startdev->default_expires * HZ;
4572 cqr->lpm = dasd_path_get_ppm(startdev);
4573 cqr->retries = startdev->default_retries;
4574 cqr->buildclk = get_tod_clock();
4575 cqr->status = DASD_CQR_FILLED;
4576
4577
4578 if (dasd_eckd_is_ese(basedev)) {
4579 set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
4580 set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
4581 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
4582 }
4583
4584 return cqr;
4585out_error:
4586 dasd_sfree_request(cqr, startdev);
4587 return ERR_PTR(ret);
4588}
4589
4590static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
4591 struct dasd_block *block,
4592 struct request *req)
4593{
4594 int cmdrtd, cmdwtd;
4595 int use_prefix;
4596 int fcx_multitrack;
4597 struct dasd_eckd_private *private;
4598 struct dasd_device *basedev;
4599 sector_t first_rec, last_rec;
4600 sector_t first_trk, last_trk;
4601 unsigned int first_offs, last_offs;
4602 unsigned int blk_per_trk, blksize;
4603 int cdlspecial;
4604 unsigned int data_size;
4605 struct dasd_ccw_req *cqr;
4606
4607 basedev = block->base;
4608 private = basedev->private;
4609
4610
4611 blksize = block->bp_block;
4612 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
4613 if (blk_per_trk == 0)
4614 return ERR_PTR(-EINVAL);
4615
4616 first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift;
4617 first_offs = sector_div(first_trk, blk_per_trk);
4618 last_rec = last_trk =
4619 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
4620 last_offs = sector_div(last_trk, blk_per_trk);
4621 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
4622
4623 fcx_multitrack = private->features.feature[40] & 0x20;
4624 data_size = blk_rq_bytes(req);
4625 if (data_size % blksize)
4626 return ERR_PTR(-EINVAL);
4627
4628 if (rq_data_dir(req) == WRITE)
4629 data_size += (last_trk - first_trk) * 4;
4630
4631
4632 cmdrtd = private->features.feature[9] & 0x20;
4633 cmdwtd = private->features.feature[12] & 0x40;
4634 use_prefix = private->features.feature[8] & 0x01;
4635
4636 cqr = NULL;
4637 if (cdlspecial || dasd_page_cache) {
4638
4639 } else if ((data_size <= private->fcx_max_data)
4640 && (fcx_multitrack || (first_trk == last_trk))) {
4641 cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
4642 first_rec, last_rec,
4643 first_trk, last_trk,
4644 first_offs, last_offs,
4645 blk_per_trk, blksize);
4646 if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&
4647 (PTR_ERR(cqr) != -ENOMEM))
4648 cqr = NULL;
4649 } else if (use_prefix &&
4650 (((rq_data_dir(req) == READ) && cmdrtd) ||
4651 ((rq_data_dir(req) == WRITE) && cmdwtd))) {
4652 cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
4653 first_rec, last_rec,
4654 first_trk, last_trk,
4655 first_offs, last_offs,
4656 blk_per_trk, blksize);
4657 if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&
4658 (PTR_ERR(cqr) != -ENOMEM))
4659 cqr = NULL;
4660 }
4661 if (!cqr)
4662 cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
4663 first_rec, last_rec,
4664 first_trk, last_trk,
4665 first_offs, last_offs,
4666 blk_per_trk, blksize);
4667 return cqr;
4668}
4669
4670static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
4671 struct dasd_block *block,
4672 struct request *req)
4673{
4674 sector_t start_padding_sectors, end_sector_offset, end_padding_sectors;
4675 unsigned int seg_len, len_to_track_end;
4676 unsigned int cidaw, cplength, datasize;
4677 sector_t first_trk, last_trk, sectors;
4678 struct dasd_eckd_private *base_priv;
4679 struct dasd_device *basedev;
4680 struct req_iterator iter;
4681 struct dasd_ccw_req *cqr;
4682 unsigned int first_offs;
4683 unsigned int trkcount;
4684 unsigned long *idaws;
4685 unsigned int size;
4686 unsigned char cmd;
4687 struct bio_vec bv;
4688 struct ccw1 *ccw;
4689 int use_prefix;
4690 void *data;
4691 char *dst;
4692
4693
4694
4695
4696
4697
4698 start_padding_sectors = blk_rq_pos(req) % DASD_RAW_SECTORS_PER_TRACK;
4699 end_sector_offset = (blk_rq_pos(req) + blk_rq_sectors(req)) %
4700 DASD_RAW_SECTORS_PER_TRACK;
4701 end_padding_sectors = (DASD_RAW_SECTORS_PER_TRACK - end_sector_offset) %
4702 DASD_RAW_SECTORS_PER_TRACK;
4703 basedev = block->base;
4704 if ((start_padding_sectors || end_padding_sectors) &&
4705 (rq_data_dir(req) == WRITE)) {
4706 DBF_DEV_EVENT(DBF_ERR, basedev,
4707 "raw write not track aligned (%llu,%llu) req %p",
4708 start_padding_sectors, end_padding_sectors, req);
4709 return ERR_PTR(-EINVAL);
4710 }
4711
4712 first_trk = blk_rq_pos(req) / DASD_RAW_SECTORS_PER_TRACK;
4713 last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
4714 DASD_RAW_SECTORS_PER_TRACK;
4715 trkcount = last_trk - first_trk + 1;
4716 first_offs = 0;
4717
4718 if (rq_data_dir(req) == READ)
4719 cmd = DASD_ECKD_CCW_READ_TRACK;
4720 else if (rq_data_dir(req) == WRITE)
4721 cmd = DASD_ECKD_CCW_WRITE_FULL_TRACK;
4722 else
4723 return ERR_PTR(-EINVAL);
4724
4725
4726
4727
4728
4729 cidaw = trkcount * DASD_RAW_BLOCK_PER_TRACK;
4730
4731
4732
4733
4734
4735 base_priv = basedev->private;
4736 use_prefix = base_priv->features.feature[8] & 0x01;
4737 if (use_prefix) {
4738 cplength = 1 + trkcount;
4739 size = sizeof(struct PFX_eckd_data) + 2;
4740 } else {
4741 cplength = 2 + trkcount;
4742 size = sizeof(struct DE_eckd_data) +
4743 sizeof(struct LRE_eckd_data) + 2;
4744 }
4745 size = ALIGN(size, 8);
4746
4747 datasize = size + cidaw * sizeof(unsigned long);
4748
4749
4750 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength,
4751 datasize, startdev, blk_mq_rq_to_pdu(req));
4752 if (IS_ERR(cqr))
4753 return cqr;
4754
4755 ccw = cqr->cpaddr;
4756 data = cqr->data;
4757
4758 if (use_prefix) {
4759 prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,
4760 startdev, 1, first_offs + 1, trkcount, 0, 0);
4761 } else {
4762 define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);
4763 ccw[-1].flags |= CCW_FLAG_CC;
4764
4765 data += sizeof(struct DE_eckd_data);
4766 locate_record_ext(ccw++, data, first_trk, first_offs + 1,
4767 trkcount, cmd, basedev, 0, 0);
4768 }
4769
4770 idaws = (unsigned long *)(cqr->data + size);
4771 len_to_track_end = 0;
4772 if (start_padding_sectors) {
4773 ccw[-1].flags |= CCW_FLAG_CC;
4774 ccw->cmd_code = cmd;
4775
4776 ccw->count = 57326;
4777
4778 len_to_track_end = 65536 - start_padding_sectors * 512;
4779 ccw->cda = (__u32)(addr_t)idaws;
4780 ccw->flags |= CCW_FLAG_IDA;
4781 ccw->flags |= CCW_FLAG_SLI;
4782 ccw++;
4783 for (sectors = 0; sectors < start_padding_sectors; sectors += 8)
4784 idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);
4785 }
4786 rq_for_each_segment(bv, req, iter) {
4787 dst = page_address(bv.bv_page) + bv.bv_offset;
4788 seg_len = bv.bv_len;
4789 if (cmd == DASD_ECKD_CCW_READ_TRACK)
4790 memset(dst, 0, seg_len);
4791 if (!len_to_track_end) {
4792 ccw[-1].flags |= CCW_FLAG_CC;
4793 ccw->cmd_code = cmd;
4794
4795 ccw->count = 57326;
4796
4797 len_to_track_end = 65536;
4798 ccw->cda = (__u32)(addr_t)idaws;
4799 ccw->flags |= CCW_FLAG_IDA;
4800 ccw->flags |= CCW_FLAG_SLI;
4801 ccw++;
4802 }
4803 len_to_track_end -= seg_len;
4804 idaws = idal_create_words(idaws, dst, seg_len);
4805 }
4806 for (sectors = 0; sectors < end_padding_sectors; sectors += 8)
4807 idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);
4808 if (blk_noretry_request(req) ||
4809 block->base->features & DASD_FEATURE_FAILFAST)
4810 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
4811 cqr->startdev = startdev;
4812 cqr->memdev = startdev;
4813 cqr->block = block;
4814 cqr->expires = startdev->default_expires * HZ;
4815 cqr->lpm = dasd_path_get_ppm(startdev);
4816 cqr->retries = startdev->default_retries;
4817 cqr->buildclk = get_tod_clock();
4818 cqr->status = DASD_CQR_FILLED;
4819
4820 return cqr;
4821}
4822
4823
4824static int
4825dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
4826{
4827 struct dasd_eckd_private *private;
4828 struct ccw1 *ccw;
4829 struct req_iterator iter;
4830 struct bio_vec bv;
4831 char *dst, *cda;
4832 unsigned int blksize, blk_per_trk, off;
4833 sector_t recid;
4834 int status;
4835
4836 if (!dasd_page_cache)
4837 goto out;
4838 private = cqr->block->base->private;
4839 blksize = cqr->block->bp_block;
4840 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
4841 recid = blk_rq_pos(req) >> cqr->block->s2b_shift;
4842 ccw = cqr->cpaddr;
4843
4844 ccw++;
4845 if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
4846 ccw++;
4847 rq_for_each_segment(bv, req, iter) {
4848 dst = page_address(bv.bv_page) + bv.bv_offset;
4849 for (off = 0; off < bv.bv_len; off += blksize) {
4850
4851 if (private->uses_cdl && recid <= 2*blk_per_trk)
4852 ccw++;
4853 if (dst) {
4854 if (ccw->flags & CCW_FLAG_IDA)
4855 cda = *((char **)((addr_t) ccw->cda));
4856 else
4857 cda = (char *)((addr_t) ccw->cda);
4858 if (dst != cda) {
4859 if (rq_data_dir(req) == READ)
4860 memcpy(dst, cda, bv.bv_len);
4861 kmem_cache_free(dasd_page_cache,
4862 (void *)((addr_t)cda & PAGE_MASK));
4863 }
4864 dst = NULL;
4865 }
4866 ccw++;
4867 recid++;
4868 }
4869 }
4870out:
4871 status = cqr->status == DASD_CQR_DONE;
4872 dasd_sfree_request(cqr, cqr->memdev);
4873 return status;
4874}
4875
4876
4877
4878
4879
4880
4881
4882
4883void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)
4884{
4885 struct ccw1 *ccw;
4886 struct PFX_eckd_data *pfxdata;
4887 struct tcw *tcw;
4888 struct tccb *tccb;
4889 struct dcw *dcw;
4890
4891 if (cqr->cpmode == 1) {
4892 tcw = cqr->cpaddr;
4893 tccb = tcw_get_tccb(tcw);
4894 dcw = (struct dcw *)&tccb->tca[0];
4895 pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
4896 pfxdata->validity.verify_base = 0;
4897 pfxdata->validity.hyper_pav = 0;
4898 } else {
4899 ccw = cqr->cpaddr;
4900 pfxdata = cqr->data;
4901 if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
4902 pfxdata->validity.verify_base = 0;
4903 pfxdata->validity.hyper_pav = 0;
4904 }
4905 }
4906}
4907
4908#define DASD_ECKD_CHANQ_MAX_SIZE 4
4909
4910static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base,
4911 struct dasd_block *block,
4912 struct request *req)
4913{
4914 struct dasd_eckd_private *private;
4915 struct dasd_device *startdev;
4916 unsigned long flags;
4917 struct dasd_ccw_req *cqr;
4918
4919 startdev = dasd_alias_get_start_dev(base);
4920 if (!startdev)
4921 startdev = base;
4922 private = startdev->private;
4923 if (private->count >= DASD_ECKD_CHANQ_MAX_SIZE)
4924 return ERR_PTR(-EBUSY);
4925
4926 spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags);
4927 private->count++;
4928 if ((base->features & DASD_FEATURE_USERAW))
4929 cqr = dasd_eckd_build_cp_raw(startdev, block, req);
4930 else
4931 cqr = dasd_eckd_build_cp(startdev, block, req);
4932 if (IS_ERR(cqr))
4933 private->count--;
4934 spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags);
4935 return cqr;
4936}
4937
4938static int dasd_eckd_free_alias_cp(struct dasd_ccw_req *cqr,
4939 struct request *req)
4940{
4941 struct dasd_eckd_private *private;
4942 unsigned long flags;
4943
4944 spin_lock_irqsave(get_ccwdev_lock(cqr->memdev->cdev), flags);
4945 private = cqr->memdev->private;
4946 private->count--;
4947 spin_unlock_irqrestore(get_ccwdev_lock(cqr->memdev->cdev), flags);
4948 return dasd_eckd_free_cp(cqr, req);
4949}
4950
4951static int
4952dasd_eckd_fill_info(struct dasd_device * device,
4953 struct dasd_information2_t * info)
4954{
4955 struct dasd_eckd_private *private = device->private;
4956
4957 info->label_block = 2;
4958 info->FBA_layout = private->uses_cdl ? 0 : 1;
4959 info->format = private->uses_cdl ? DASD_FORMAT_CDL : DASD_FORMAT_LDL;
4960 info->characteristics_size = sizeof(private->rdc_data);
4961 memcpy(info->characteristics, &private->rdc_data,
4962 sizeof(private->rdc_data));
4963 info->confdata_size = min((unsigned long)private->conf_len,
4964 sizeof(info->configuration_data));
4965 memcpy(info->configuration_data, private->conf_data,
4966 info->confdata_size);
4967 return 0;
4968}
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979static int
4980dasd_eckd_release(struct dasd_device *device)
4981{
4982 struct dasd_ccw_req *cqr;
4983 int rc;
4984 struct ccw1 *ccw;
4985 int useglobal;
4986
4987 if (!capable(CAP_SYS_ADMIN))
4988 return -EACCES;
4989
4990 useglobal = 0;
4991 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device, NULL);
4992 if (IS_ERR(cqr)) {
4993 mutex_lock(&dasd_reserve_mutex);
4994 useglobal = 1;
4995 cqr = &dasd_reserve_req->cqr;
4996 memset(cqr, 0, sizeof(*cqr));
4997 memset(&dasd_reserve_req->ccw, 0,
4998 sizeof(dasd_reserve_req->ccw));
4999 cqr->cpaddr = &dasd_reserve_req->ccw;
5000 cqr->data = &dasd_reserve_req->data;
5001 cqr->magic = DASD_ECKD_MAGIC;
5002 }
5003 ccw = cqr->cpaddr;
5004 ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
5005 ccw->flags |= CCW_FLAG_SLI;
5006 ccw->count = 32;
5007 ccw->cda = (__u32)(addr_t) cqr->data;
5008 cqr->startdev = device;
5009 cqr->memdev = device;
5010 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
5011 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
5012 cqr->retries = 2;
5013 cqr->expires = 2 * HZ;
5014 cqr->buildclk = get_tod_clock();
5015 cqr->status = DASD_CQR_FILLED;
5016
5017 rc = dasd_sleep_on_immediatly(cqr);
5018 if (!rc)
5019 clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);
5020
5021 if (useglobal)
5022 mutex_unlock(&dasd_reserve_mutex);
5023 else
5024 dasd_sfree_request(cqr, cqr->memdev);
5025 return rc;
5026}
5027
5028
5029
5030
5031
5032
5033
5034static int
5035dasd_eckd_reserve(struct dasd_device *device)
5036{
5037 struct dasd_ccw_req *cqr;
5038 int rc;
5039 struct ccw1 *ccw;
5040 int useglobal;
5041
5042 if (!capable(CAP_SYS_ADMIN))
5043 return -EACCES;
5044
5045 useglobal = 0;
5046 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device, NULL);
5047 if (IS_ERR(cqr)) {
5048 mutex_lock(&dasd_reserve_mutex);
5049 useglobal = 1;
5050 cqr = &dasd_reserve_req->cqr;
5051 memset(cqr, 0, sizeof(*cqr));
5052 memset(&dasd_reserve_req->ccw, 0,
5053 sizeof(dasd_reserve_req->ccw));
5054 cqr->cpaddr = &dasd_reserve_req->ccw;
5055 cqr->data = &dasd_reserve_req->data;
5056 cqr->magic = DASD_ECKD_MAGIC;
5057 }
5058 ccw = cqr->cpaddr;
5059 ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
5060 ccw->flags |= CCW_FLAG_SLI;
5061 ccw->count = 32;
5062 ccw->cda = (__u32)(addr_t) cqr->data;
5063 cqr->startdev = device;
5064 cqr->memdev = device;
5065 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
5066 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
5067 cqr->retries = 2;
5068 cqr->expires = 2 * HZ;
5069 cqr->buildclk = get_tod_clock();
5070 cqr->status = DASD_CQR_FILLED;
5071
5072 rc = dasd_sleep_on_immediatly(cqr);
5073 if (!rc)
5074 set_bit(DASD_FLAG_IS_RESERVED, &device->flags);
5075
5076 if (useglobal)
5077 mutex_unlock(&dasd_reserve_mutex);
5078 else
5079 dasd_sfree_request(cqr, cqr->memdev);
5080 return rc;
5081}
5082
5083
5084
5085
5086
5087
5088static int
5089dasd_eckd_steal_lock(struct dasd_device *device)
5090{
5091 struct dasd_ccw_req *cqr;
5092 int rc;
5093 struct ccw1 *ccw;
5094 int useglobal;
5095
5096 if (!capable(CAP_SYS_ADMIN))
5097 return -EACCES;
5098
5099 useglobal = 0;
5100 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device, NULL);
5101 if (IS_ERR(cqr)) {
5102 mutex_lock(&dasd_reserve_mutex);
5103 useglobal = 1;
5104 cqr = &dasd_reserve_req->cqr;
5105 memset(cqr, 0, sizeof(*cqr));
5106 memset(&dasd_reserve_req->ccw, 0,
5107 sizeof(dasd_reserve_req->ccw));
5108 cqr->cpaddr = &dasd_reserve_req->ccw;
5109 cqr->data = &dasd_reserve_req->data;
5110 cqr->magic = DASD_ECKD_MAGIC;
5111 }
5112 ccw = cqr->cpaddr;
5113 ccw->cmd_code = DASD_ECKD_CCW_SLCK;
5114 ccw->flags |= CCW_FLAG_SLI;
5115 ccw->count = 32;
5116 ccw->cda = (__u32)(addr_t) cqr->data;
5117 cqr->startdev = device;
5118 cqr->memdev = device;
5119 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
5120 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
5121 cqr->retries = 2;
5122 cqr->expires = 2 * HZ;
5123 cqr->buildclk = get_tod_clock();
5124 cqr->status = DASD_CQR_FILLED;
5125
5126 rc = dasd_sleep_on_immediatly(cqr);
5127 if (!rc)
5128 set_bit(DASD_FLAG_IS_RESERVED, &device->flags);
5129
5130 if (useglobal)
5131 mutex_unlock(&dasd_reserve_mutex);
5132 else
5133 dasd_sfree_request(cqr, cqr->memdev);
5134 return rc;
5135}
5136
5137
5138
5139
5140
5141
5142
5143static int dasd_eckd_snid(struct dasd_device *device,
5144 void __user *argp)
5145{
5146 struct dasd_ccw_req *cqr;
5147 int rc;
5148 struct ccw1 *ccw;
5149 int useglobal;
5150 struct dasd_snid_ioctl_data usrparm;
5151
5152 if (!capable(CAP_SYS_ADMIN))
5153 return -EACCES;
5154
5155 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
5156 return -EFAULT;
5157
5158 useglobal = 0;
5159 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1,
5160 sizeof(struct dasd_snid_data), device,
5161 NULL);
5162 if (IS_ERR(cqr)) {
5163 mutex_lock(&dasd_reserve_mutex);
5164 useglobal = 1;
5165 cqr = &dasd_reserve_req->cqr;
5166 memset(cqr, 0, sizeof(*cqr));
5167 memset(&dasd_reserve_req->ccw, 0,
5168 sizeof(dasd_reserve_req->ccw));
5169 cqr->cpaddr = &dasd_reserve_req->ccw;
5170 cqr->data = &dasd_reserve_req->data;
5171 cqr->magic = DASD_ECKD_MAGIC;
5172 }
5173 ccw = cqr->cpaddr;
5174 ccw->cmd_code = DASD_ECKD_CCW_SNID;
5175 ccw->flags |= CCW_FLAG_SLI;
5176 ccw->count = 12;
5177 ccw->cda = (__u32)(addr_t) cqr->data;
5178 cqr->startdev = device;
5179 cqr->memdev = device;
5180 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
5181 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
5182 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
5183 cqr->retries = 5;
5184 cqr->expires = 10 * HZ;
5185 cqr->buildclk = get_tod_clock();
5186 cqr->status = DASD_CQR_FILLED;
5187 cqr->lpm = usrparm.path_mask;
5188
5189 rc = dasd_sleep_on_immediatly(cqr);
5190
5191 if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask))
5192 rc = -EIO;
5193 if (!rc) {
5194 usrparm.data = *((struct dasd_snid_data *)cqr->data);
5195 if (copy_to_user(argp, &usrparm, sizeof(usrparm)))
5196 rc = -EFAULT;
5197 }
5198
5199 if (useglobal)
5200 mutex_unlock(&dasd_reserve_mutex);
5201 else
5202 dasd_sfree_request(cqr, cqr->memdev);
5203 return rc;
5204}
5205
5206
5207
5208
5209static int
5210dasd_eckd_performance(struct dasd_device *device, void __user *argp)
5211{
5212 struct dasd_psf_prssd_data *prssdp;
5213 struct dasd_rssd_perf_stats_t *stats;
5214 struct dasd_ccw_req *cqr;
5215 struct ccw1 *ccw;
5216 int rc;
5217
5218 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 + 1 ,
5219 (sizeof(struct dasd_psf_prssd_data) +
5220 sizeof(struct dasd_rssd_perf_stats_t)),
5221 device, NULL);
5222 if (IS_ERR(cqr)) {
5223 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
5224 "Could not allocate initialization request");
5225 return PTR_ERR(cqr);
5226 }
5227 cqr->startdev = device;
5228 cqr->memdev = device;
5229 cqr->retries = 0;
5230 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
5231 cqr->expires = 10 * HZ;
5232
5233
5234 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
5235 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
5236 prssdp->order = PSF_ORDER_PRSSD;
5237 prssdp->suborder = 0x01;
5238 prssdp->varies[1] = 0x01;
5239
5240 ccw = cqr->cpaddr;
5241 ccw->cmd_code = DASD_ECKD_CCW_PSF;
5242 ccw->count = sizeof(struct dasd_psf_prssd_data);
5243 ccw->flags |= CCW_FLAG_CC;
5244 ccw->cda = (__u32)(addr_t) prssdp;
5245
5246
5247 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
5248 memset(stats, 0, sizeof(struct dasd_rssd_perf_stats_t));
5249
5250 ccw++;
5251 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
5252 ccw->count = sizeof(struct dasd_rssd_perf_stats_t);
5253 ccw->cda = (__u32)(addr_t) stats;
5254
5255 cqr->buildclk = get_tod_clock();
5256 cqr->status = DASD_CQR_FILLED;
5257 rc = dasd_sleep_on(cqr);
5258 if (rc == 0) {
5259 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
5260 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
5261 if (copy_to_user(argp, stats,
5262 sizeof(struct dasd_rssd_perf_stats_t)))
5263 rc = -EFAULT;
5264 }
5265 dasd_sfree_request(cqr, cqr->memdev);
5266 return rc;
5267}
5268
5269
5270
5271
5272
5273static int
5274dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp)
5275{
5276 struct dasd_eckd_private *private = device->private;
5277 struct attrib_data_t attrib = private->attrib;
5278 int rc;
5279
5280 if (!capable(CAP_SYS_ADMIN))
5281 return -EACCES;
5282 if (!argp)
5283 return -EINVAL;
5284
5285 rc = 0;
5286 if (copy_to_user(argp, (long *) &attrib,
5287 sizeof(struct attrib_data_t)))
5288 rc = -EFAULT;
5289
5290 return rc;
5291}
5292
5293
5294
5295
5296
5297static int
5298dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
5299{
5300 struct dasd_eckd_private *private = device->private;
5301 struct attrib_data_t attrib;
5302
5303 if (!capable(CAP_SYS_ADMIN))
5304 return -EACCES;
5305 if (!argp)
5306 return -EINVAL;
5307
5308 if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t)))
5309 return -EFAULT;
5310 private->attrib = attrib;
5311
5312 dev_info(&device->cdev->dev,
5313 "The DASD cache mode was set to %x (%i cylinder prestage)\n",
5314 private->attrib.operation, private->attrib.nr_cyl);
5315 return 0;
5316}
5317
5318
5319
5320
5321
5322static int dasd_symm_io(struct dasd_device *device, void __user *argp)
5323{
5324 struct dasd_symmio_parms usrparm;
5325 char *psf_data, *rssd_result;
5326 struct dasd_ccw_req *cqr;
5327 struct ccw1 *ccw;
5328 char psf0, psf1;
5329 int rc;
5330
5331 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
5332 return -EACCES;
5333 psf0 = psf1 = 0;
5334
5335
5336 rc = -EFAULT;
5337 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
5338 goto out;
5339 if (is_compat_task()) {
5340
5341 rc = -EINVAL;
5342 if ((usrparm.psf_data >> 32) != 0)
5343 goto out;
5344 if ((usrparm.rssd_result >> 32) != 0)
5345 goto out;
5346 usrparm.psf_data &= 0x7fffffffULL;
5347 usrparm.rssd_result &= 0x7fffffffULL;
5348 }
5349
5350 psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);
5351 rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);
5352 if (!psf_data || !rssd_result) {
5353 rc = -ENOMEM;
5354 goto out_free;
5355 }
5356
5357
5358 rc = -EFAULT;
5359 if (copy_from_user(psf_data,
5360 (void __user *)(unsigned long) usrparm.psf_data,
5361 usrparm.psf_data_len))
5362 goto out_free;
5363 psf0 = psf_data[0];
5364 psf1 = psf_data[1];
5365
5366
5367 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2, 0, device, NULL);
5368 if (IS_ERR(cqr)) {
5369 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
5370 "Could not allocate initialization request");
5371 rc = PTR_ERR(cqr);
5372 goto out_free;
5373 }
5374
5375 cqr->startdev = device;
5376 cqr->memdev = device;
5377 cqr->retries = 3;
5378 cqr->expires = 10 * HZ;
5379 cqr->buildclk = get_tod_clock();
5380 cqr->status = DASD_CQR_FILLED;
5381
5382
5383 ccw = cqr->cpaddr;
5384
5385
5386 ccw->cmd_code = DASD_ECKD_CCW_PSF;
5387 ccw->count = usrparm.psf_data_len;
5388 ccw->flags |= CCW_FLAG_CC;
5389 ccw->cda = (__u32)(addr_t) psf_data;
5390
5391 ccw++;
5392
5393
5394 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
5395 ccw->count = usrparm.rssd_result_len;
5396 ccw->flags = CCW_FLAG_SLI ;
5397 ccw->cda = (__u32)(addr_t) rssd_result;
5398
5399 rc = dasd_sleep_on(cqr);
5400 if (rc)
5401 goto out_sfree;
5402
5403 rc = -EFAULT;
5404 if (copy_to_user((void __user *)(unsigned long) usrparm.rssd_result,
5405 rssd_result, usrparm.rssd_result_len))
5406 goto out_sfree;
5407 rc = 0;
5408
5409out_sfree:
5410 dasd_sfree_request(cqr, cqr->memdev);
5411out_free:
5412 kfree(rssd_result);
5413 kfree(psf_data);
5414out:
5415 DBF_DEV_EVENT(DBF_WARNING, device,
5416 "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",
5417 (int) psf0, (int) psf1, rc);
5418 return rc;
5419}
5420
5421static int
5422dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
5423{
5424 struct dasd_device *device = block->base;
5425
5426 switch (cmd) {
5427 case BIODASDGATTR:
5428 return dasd_eckd_get_attrib(device, argp);
5429 case BIODASDSATTR:
5430 return dasd_eckd_set_attrib(device, argp);
5431 case BIODASDPSRD:
5432 return dasd_eckd_performance(device, argp);
5433 case BIODASDRLSE:
5434 return dasd_eckd_release(device);
5435 case BIODASDRSRV:
5436 return dasd_eckd_reserve(device);
5437 case BIODASDSLCK:
5438 return dasd_eckd_steal_lock(device);
5439 case BIODASDSNID:
5440 return dasd_eckd_snid(device, argp);
5441 case BIODASDSYMMIO:
5442 return dasd_symm_io(device, argp);
5443 default:
5444 return -ENOTTY;
5445 }
5446}
5447
5448
5449
5450
5451
5452static int
5453dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
5454{
5455 int len, count;
5456 char *datap;
5457
5458 len = 0;
5459 while (from <= to) {
5460 len += sprintf(page + len, PRINTK_HEADER
5461 " CCW %p: %08X %08X DAT:",
5462 from, ((int *) from)[0], ((int *) from)[1]);
5463
5464
5465 if (from->flags & CCW_FLAG_IDA)
5466 datap = (char *) *((addr_t *) (addr_t) from->cda);
5467 else
5468 datap = (char *) ((addr_t) from->cda);
5469
5470
5471 for (count = 0; count < from->count && count < 32; count++) {
5472 if (count % 8 == 0) len += sprintf(page + len, " ");
5473 if (count % 4 == 0) len += sprintf(page + len, " ");
5474 len += sprintf(page + len, "%02x", datap[count]);
5475 }
5476 len += sprintf(page + len, "\n");
5477 from++;
5478 }
5479 return len;
5480}
5481
5482static void
5483dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb,
5484 char *reason)
5485{
5486 u64 *sense;
5487 u64 *stat;
5488
5489 sense = (u64 *) dasd_get_sense(irb);
5490 stat = (u64 *) &irb->scsw;
5491 if (sense) {
5492 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : "
5493 "%016llx %016llx %016llx %016llx",
5494 reason, *stat, *((u32 *) (stat + 1)),
5495 sense[0], sense[1], sense[2], sense[3]);
5496 } else {
5497 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : %s",
5498 reason, *stat, *((u32 *) (stat + 1)),
5499 "NO VALID SENSE");
5500 }
5501}
5502
5503
5504
5505
5506
5507static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
5508 struct dasd_ccw_req *req, struct irb *irb)
5509{
5510 char *page;
5511 struct ccw1 *first, *last, *fail, *from, *to;
5512 int len, sl, sct;
5513
5514 page = (char *) get_zeroed_page(GFP_ATOMIC);
5515 if (page == NULL) {
5516 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
5517 "No memory to dump sense data\n");
5518 return;
5519 }
5520
5521 len = sprintf(page, PRINTK_HEADER
5522 " I/O status report for device %s:\n",
5523 dev_name(&device->cdev->dev));
5524 len += sprintf(page + len, PRINTK_HEADER
5525 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
5526 "CS:%02X RC:%d\n",
5527 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
5528 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
5529 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
5530 req ? req->intrc : 0);
5531 len += sprintf(page + len, PRINTK_HEADER
5532 " device %s: Failing CCW: %p\n",
5533 dev_name(&device->cdev->dev),
5534 (void *) (addr_t) irb->scsw.cmd.cpa);
5535 if (irb->esw.esw0.erw.cons) {
5536 for (sl = 0; sl < 4; sl++) {
5537 len += sprintf(page + len, PRINTK_HEADER
5538 " Sense(hex) %2d-%2d:",
5539 (8 * sl), ((8 * sl) + 7));
5540
5541 for (sct = 0; sct < 8; sct++) {
5542 len += sprintf(page + len, " %02x",
5543 irb->ecw[8 * sl + sct]);
5544 }
5545 len += sprintf(page + len, "\n");
5546 }
5547
5548 if (irb->ecw[27] & DASD_SENSE_BIT_0) {
5549
5550 sprintf(page + len, PRINTK_HEADER
5551 " 24 Byte: %x MSG %x, "
5552 "%s MSGb to SYSOP\n",
5553 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
5554 irb->ecw[1] & 0x10 ? "" : "no");
5555 } else {
5556
5557 sprintf(page + len, PRINTK_HEADER
5558 " 32 Byte: Format: %x "
5559 "Exception class %x\n",
5560 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
5561 }
5562 } else {
5563 sprintf(page + len, PRINTK_HEADER
5564 " SORRY - NO VALID SENSE AVAILABLE\n");
5565 }
5566 printk(KERN_ERR "%s", page);
5567
5568 if (req) {
5569
5570
5571
5572 first = req->cpaddr;
5573 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
5574 to = min(first + 6, last);
5575 len = sprintf(page, PRINTK_HEADER
5576 " Related CP in req: %p\n", req);
5577 dasd_eckd_dump_ccw_range(first, to, page + len);
5578 printk(KERN_ERR "%s", page);
5579
5580
5581
5582 len = 0;
5583 from = ++to;
5584 fail = (struct ccw1 *)(addr_t)
5585 irb->scsw.cmd.cpa;
5586 if (from < fail - 2) {
5587 from = fail - 2;
5588 len += sprintf(page, PRINTK_HEADER "......\n");
5589 }
5590 to = min(fail + 1, last);
5591 len += dasd_eckd_dump_ccw_range(from, to, page + len);
5592
5593
5594 from = max(from, ++to);
5595 if (from < last - 1) {
5596 from = last - 1;
5597 len += sprintf(page + len, PRINTK_HEADER "......\n");
5598 }
5599 len += dasd_eckd_dump_ccw_range(from, last, page + len);
5600 if (len > 0)
5601 printk(KERN_ERR "%s", page);
5602 }
5603 free_page((unsigned long) page);
5604}
5605
5606
5607
5608
5609
5610static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
5611 struct dasd_ccw_req *req, struct irb *irb)
5612{
5613 char *page;
5614 int len, sl, sct, residual;
5615 struct tsb *tsb;
5616 u8 *sense, *rcq;
5617
5618 page = (char *) get_zeroed_page(GFP_ATOMIC);
5619 if (page == NULL) {
5620 DBF_DEV_EVENT(DBF_WARNING, device, " %s",
5621 "No memory to dump sense data");
5622 return;
5623 }
5624
5625 len = sprintf(page, PRINTK_HEADER
5626 " I/O status report for device %s:\n",
5627 dev_name(&device->cdev->dev));
5628 len += sprintf(page + len, PRINTK_HEADER
5629 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
5630 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n",
5631 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
5632 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
5633 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
5634 irb->scsw.tm.fcxs,
5635 (irb->scsw.tm.ifob << 7) | irb->scsw.tm.sesq,
5636 req ? req->intrc : 0);
5637 len += sprintf(page + len, PRINTK_HEADER
5638 " device %s: Failing TCW: %p\n",
5639 dev_name(&device->cdev->dev),
5640 (void *) (addr_t) irb->scsw.tm.tcw);
5641
5642 tsb = NULL;
5643 sense = NULL;
5644 if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs & 0x01))
5645 tsb = tcw_get_tsb(
5646 (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
5647
5648 if (tsb) {
5649 len += sprintf(page + len, PRINTK_HEADER
5650 " tsb->length %d\n", tsb->length);
5651 len += sprintf(page + len, PRINTK_HEADER
5652 " tsb->flags %x\n", tsb->flags);
5653 len += sprintf(page + len, PRINTK_HEADER
5654 " tsb->dcw_offset %d\n", tsb->dcw_offset);
5655 len += sprintf(page + len, PRINTK_HEADER
5656 " tsb->count %d\n", tsb->count);
5657 residual = tsb->count - 28;
5658 len += sprintf(page + len, PRINTK_HEADER
5659 " residual %d\n", residual);
5660
5661 switch (tsb->flags & 0x07) {
5662 case 1:
5663 len += sprintf(page + len, PRINTK_HEADER
5664 " tsb->tsa.iostat.dev_time %d\n",
5665 tsb->tsa.iostat.dev_time);
5666 len += sprintf(page + len, PRINTK_HEADER
5667 " tsb->tsa.iostat.def_time %d\n",
5668 tsb->tsa.iostat.def_time);
5669 len += sprintf(page + len, PRINTK_HEADER
5670 " tsb->tsa.iostat.queue_time %d\n",
5671 tsb->tsa.iostat.queue_time);
5672 len += sprintf(page + len, PRINTK_HEADER
5673 " tsb->tsa.iostat.dev_busy_time %d\n",
5674 tsb->tsa.iostat.dev_busy_time);
5675 len += sprintf(page + len, PRINTK_HEADER
5676 " tsb->tsa.iostat.dev_act_time %d\n",
5677 tsb->tsa.iostat.dev_act_time);
5678 sense = tsb->tsa.iostat.sense;
5679 break;
5680 case 2:
5681 len += sprintf(page + len, PRINTK_HEADER
5682 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
5683 for (sl = 0; sl < 2; sl++) {
5684 len += sprintf(page + len, PRINTK_HEADER
5685 " tsb->tsa.ddpc.rcq %2d-%2d: ",
5686 (8 * sl), ((8 * sl) + 7));
5687 rcq = tsb->tsa.ddpc.rcq;
5688 for (sct = 0; sct < 8; sct++) {
5689 len += sprintf(page + len, " %02x",
5690 rcq[8 * sl + sct]);
5691 }
5692 len += sprintf(page + len, "\n");
5693 }
5694 sense = tsb->tsa.ddpc.sense;
5695 break;
5696 case 3:
5697 len += sprintf(page + len, PRINTK_HEADER
5698 " tsb->tsa.intrg.: not supported yet\n");
5699 break;
5700 }
5701
5702 if (sense) {
5703 for (sl = 0; sl < 4; sl++) {
5704 len += sprintf(page + len, PRINTK_HEADER
5705 " Sense(hex) %2d-%2d:",
5706 (8 * sl), ((8 * sl) + 7));
5707 for (sct = 0; sct < 8; sct++) {
5708 len += sprintf(page + len, " %02x",
5709 sense[8 * sl + sct]);
5710 }
5711 len += sprintf(page + len, "\n");
5712 }
5713
5714 if (sense[27] & DASD_SENSE_BIT_0) {
5715
5716 sprintf(page + len, PRINTK_HEADER
5717 " 24 Byte: %x MSG %x, "
5718 "%s MSGb to SYSOP\n",
5719 sense[7] >> 4, sense[7] & 0x0f,
5720 sense[1] & 0x10 ? "" : "no");
5721 } else {
5722
5723 sprintf(page + len, PRINTK_HEADER
5724 " 32 Byte: Format: %x "
5725 "Exception class %x\n",
5726 sense[6] & 0x0f, sense[22] >> 4);
5727 }
5728 } else {
5729 sprintf(page + len, PRINTK_HEADER
5730 " SORRY - NO VALID SENSE AVAILABLE\n");
5731 }
5732 } else {
5733 sprintf(page + len, PRINTK_HEADER
5734 " SORRY - NO TSB DATA AVAILABLE\n");
5735 }
5736 printk(KERN_ERR "%s", page);
5737 free_page((unsigned long) page);
5738}
5739
5740static void dasd_eckd_dump_sense(struct dasd_device *device,
5741 struct dasd_ccw_req *req, struct irb *irb)
5742{
5743 u8 *sense = dasd_get_sense(irb);
5744
5745 if (scsw_is_tm(&irb->scsw)) {
5746
5747
5748
5749
5750
5751 if (sense && (sense[1] & SNS1_FILE_PROTECTED) &&
5752 test_bit(DASD_CQR_SUPPRESS_FP, &req->flags))
5753 return;
5754 if (scsw_cstat(&irb->scsw) == 0x40 &&
5755 test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
5756 return;
5757
5758 dasd_eckd_dump_sense_tcw(device, req, irb);
5759 } else {
5760
5761
5762
5763
5764
5765 if (sense && sense[0] & SNS0_CMD_REJECT &&
5766 test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))
5767 return;
5768
5769 if (sense && sense[1] & SNS1_NO_REC_FOUND &&
5770 test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags))
5771 return;
5772
5773 dasd_eckd_dump_sense_ccw(device, req, irb);
5774 }
5775}
5776
5777static int dasd_eckd_pm_freeze(struct dasd_device *device)
5778{
5779
5780
5781
5782
5783
5784 dasd_alias_remove_device(device);
5785 dasd_alias_disconnect_device_from_lcu(device);
5786
5787 return 0;
5788}
5789
5790static int dasd_eckd_restore_device(struct dasd_device *device)
5791{
5792 struct dasd_eckd_private *private = device->private;
5793 struct dasd_eckd_characteristics temp_rdc_data;
5794 int rc;
5795 struct dasd_uid temp_uid;
5796 unsigned long flags;
5797 unsigned long cqr_flags = 0;
5798
5799
5800 rc = dasd_eckd_read_conf(device);
5801 if (rc) {
5802 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
5803 "Read configuration data failed, rc=%d", rc);
5804 goto out_err;
5805 }
5806
5807 dasd_eckd_get_uid(device, &temp_uid);
5808
5809 rc = dasd_eckd_generate_uid(device);
5810 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
5811 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
5812 dev_err(&device->cdev->dev, "The UID of the DASD has "
5813 "changed\n");
5814 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
5815 if (rc)
5816 goto out_err;
5817
5818
5819 rc = dasd_alias_make_device_known_to_lcu(device);
5820 if (rc)
5821 goto out_err;
5822
5823 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr_flags);
5824 dasd_eckd_validate_server(device, cqr_flags);
5825
5826
5827 rc = dasd_eckd_read_conf(device);
5828 if (rc) {
5829 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
5830 "Read configuration data failed, rc=%d", rc);
5831 goto out_err2;
5832 }
5833
5834
5835 dasd_eckd_read_features(device);
5836
5837
5838 dasd_eckd_read_vol_info(device);
5839
5840
5841 dasd_eckd_read_ext_pool_info(device);
5842
5843
5844 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
5845 &temp_rdc_data, 64);
5846 if (rc) {
5847 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
5848 "Read device characteristic failed, rc=%d", rc);
5849 goto out_err2;
5850 }
5851 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
5852 memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data));
5853 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
5854
5855
5856 dasd_alias_add_device(device);
5857
5858 return 0;
5859
5860out_err2:
5861 dasd_alias_disconnect_device_from_lcu(device);
5862out_err:
5863 return -1;
5864}
5865
5866static int dasd_eckd_reload_device(struct dasd_device *device)
5867{
5868 struct dasd_eckd_private *private = device->private;
5869 int rc, old_base;
5870 char print_uid[60];
5871 struct dasd_uid uid;
5872 unsigned long flags;
5873
5874
5875
5876
5877
5878 dasd_alias_remove_device(device);
5879
5880 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
5881 old_base = private->uid.base_unit_addr;
5882 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
5883
5884
5885 rc = dasd_eckd_read_conf(device);
5886 if (rc)
5887 goto out_err;
5888
5889 rc = dasd_eckd_generate_uid(device);
5890 if (rc)
5891 goto out_err;
5892
5893
5894
5895
5896 dasd_alias_update_add_device(device);
5897
5898 dasd_eckd_get_uid(device, &uid);
5899
5900 if (old_base != uid.base_unit_addr) {
5901 if (strlen(uid.vduit) > 0)
5902 snprintf(print_uid, sizeof(print_uid),
5903 "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial,
5904 uid.ssid, uid.base_unit_addr, uid.vduit);
5905 else
5906 snprintf(print_uid, sizeof(print_uid),
5907 "%s.%s.%04x.%02x", uid.vendor, uid.serial,
5908 uid.ssid, uid.base_unit_addr);
5909
5910 dev_info(&device->cdev->dev,
5911 "An Alias device was reassigned to a new base device "
5912 "with UID: %s\n", print_uid);
5913 }
5914 return 0;
5915
5916out_err:
5917 return -1;
5918}
5919
5920static int dasd_eckd_read_message_buffer(struct dasd_device *device,
5921 struct dasd_rssd_messages *messages,
5922 __u8 lpum)
5923{
5924 struct dasd_rssd_messages *message_buf;
5925 struct dasd_psf_prssd_data *prssdp;
5926 struct dasd_ccw_req *cqr;
5927 struct ccw1 *ccw;
5928 int rc;
5929
5930 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 + 1 ,
5931 (sizeof(struct dasd_psf_prssd_data) +
5932 sizeof(struct dasd_rssd_messages)),
5933 device, NULL);
5934 if (IS_ERR(cqr)) {
5935 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
5936 "Could not allocate read message buffer request");
5937 return PTR_ERR(cqr);
5938 }
5939
5940 cqr->lpm = lpum;
5941retry:
5942 cqr->startdev = device;
5943 cqr->memdev = device;
5944 cqr->block = NULL;
5945 cqr->expires = 10 * HZ;
5946 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
5947
5948
5949
5950 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
5951 cqr->retries = 256;
5952
5953
5954 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
5955 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
5956 prssdp->order = PSF_ORDER_PRSSD;
5957 prssdp->suborder = 0x03;
5958
5959
5960 ccw = cqr->cpaddr;
5961 ccw->cmd_code = DASD_ECKD_CCW_PSF;
5962 ccw->count = sizeof(struct dasd_psf_prssd_data);
5963 ccw->flags |= CCW_FLAG_CC;
5964 ccw->flags |= CCW_FLAG_SLI;
5965 ccw->cda = (__u32)(addr_t) prssdp;
5966
5967
5968 message_buf = (struct dasd_rssd_messages *) (prssdp + 1);
5969 memset(message_buf, 0, sizeof(struct dasd_rssd_messages));
5970
5971 ccw++;
5972 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
5973 ccw->count = sizeof(struct dasd_rssd_messages);
5974 ccw->flags |= CCW_FLAG_SLI;
5975 ccw->cda = (__u32)(addr_t) message_buf;
5976
5977 cqr->buildclk = get_tod_clock();
5978 cqr->status = DASD_CQR_FILLED;
5979 rc = dasd_sleep_on_immediatly(cqr);
5980 if (rc == 0) {
5981 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
5982 message_buf = (struct dasd_rssd_messages *)
5983 (prssdp + 1);
5984 memcpy(messages, message_buf,
5985 sizeof(struct dasd_rssd_messages));
5986 } else if (cqr->lpm) {
5987
5988
5989
5990
5991
5992 cqr->lpm = 0;
5993 goto retry;
5994 } else
5995 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
5996 "Reading messages failed with rc=%d\n"
5997 , rc);
5998 dasd_sfree_request(cqr, cqr->memdev);
5999 return rc;
6000}
6001
6002static int dasd_eckd_query_host_access(struct dasd_device *device,
6003 struct dasd_psf_query_host_access *data)
6004{
6005 struct dasd_eckd_private *private = device->private;
6006 struct dasd_psf_query_host_access *host_access;
6007 struct dasd_psf_prssd_data *prssdp;
6008 struct dasd_ccw_req *cqr;
6009 struct ccw1 *ccw;
6010 int rc;
6011
6012
6013 if (!device->block && private->lcu->pav == HYPER_PAV)
6014 return -EOPNOTSUPP;
6015
6016
6017 if (!(private->features.feature[14] & 0x80))
6018 return -EOPNOTSUPP;
6019
6020 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 + 1 ,
6021 sizeof(struct dasd_psf_prssd_data) + 1,
6022 device, NULL);
6023 if (IS_ERR(cqr)) {
6024 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
6025 "Could not allocate read message buffer request");
6026 return PTR_ERR(cqr);
6027 }
6028 host_access = kzalloc(sizeof(*host_access), GFP_KERNEL | GFP_DMA);
6029 if (!host_access) {
6030 dasd_sfree_request(cqr, device);
6031 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
6032 "Could not allocate host_access buffer");
6033 return -ENOMEM;
6034 }
6035 cqr->startdev = device;
6036 cqr->memdev = device;
6037 cqr->block = NULL;
6038 cqr->retries = 256;
6039 cqr->expires = 10 * HZ;
6040
6041
6042 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
6043 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
6044 prssdp->order = PSF_ORDER_PRSSD;
6045 prssdp->suborder = PSF_SUBORDER_QHA;
6046
6047 prssdp->lss = private->ned->ID;
6048 prssdp->volume = private->ned->unit_addr;
6049
6050
6051 ccw = cqr->cpaddr;
6052 ccw->cmd_code = DASD_ECKD_CCW_PSF;
6053 ccw->count = sizeof(struct dasd_psf_prssd_data);
6054 ccw->flags |= CCW_FLAG_CC;
6055 ccw->flags |= CCW_FLAG_SLI;
6056 ccw->cda = (__u32)(addr_t) prssdp;
6057
6058
6059 ccw++;
6060 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
6061 ccw->count = sizeof(struct dasd_psf_query_host_access);
6062 ccw->flags |= CCW_FLAG_SLI;
6063 ccw->cda = (__u32)(addr_t) host_access;
6064
6065 cqr->buildclk = get_tod_clock();
6066 cqr->status = DASD_CQR_FILLED;
6067
6068 __set_bit(DASD_CQR_SUPPRESS_CR, &cqr->flags);
6069 rc = dasd_sleep_on_interruptible(cqr);
6070 if (rc == 0) {
6071 *data = *host_access;
6072 } else {
6073 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
6074 "Reading host access data failed with rc=%d\n",
6075 rc);
6076 rc = -EOPNOTSUPP;
6077 }
6078
6079 dasd_sfree_request(cqr, cqr->memdev);
6080 kfree(host_access);
6081 return rc;
6082}
6083
6084
6085
6086static int dasd_eckd_host_access_count(struct dasd_device *device)
6087{
6088 struct dasd_psf_query_host_access *access;
6089 struct dasd_ckd_path_group_entry *entry;
6090 struct dasd_ckd_host_information *info;
6091 int count = 0;
6092 int rc, i;
6093
6094 access = kzalloc(sizeof(*access), GFP_NOIO);
6095 if (!access) {
6096 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
6097 "Could not allocate access buffer");
6098 return -ENOMEM;
6099 }
6100 rc = dasd_eckd_query_host_access(device, access);
6101 if (rc) {
6102 kfree(access);
6103 return rc;
6104 }
6105
6106 info = (struct dasd_ckd_host_information *)
6107 access->host_access_information;
6108 for (i = 0; i < info->entry_count; i++) {
6109 entry = (struct dasd_ckd_path_group_entry *)
6110 (info->entry + i * info->entry_size);
6111 if (entry->status_flags & DASD_ECKD_PG_GROUPED)
6112 count++;
6113 }
6114
6115 kfree(access);
6116 return count;
6117}
6118
6119
6120
6121
6122static int dasd_hosts_print(struct dasd_device *device, struct seq_file *m)
6123{
6124 struct dasd_psf_query_host_access *access;
6125 struct dasd_ckd_path_group_entry *entry;
6126 struct dasd_ckd_host_information *info;
6127 char sysplex[9] = "";
6128 int rc, i;
6129
6130 access = kzalloc(sizeof(*access), GFP_NOIO);
6131 if (!access) {
6132 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
6133 "Could not allocate access buffer");
6134 return -ENOMEM;
6135 }
6136 rc = dasd_eckd_query_host_access(device, access);
6137 if (rc) {
6138 kfree(access);
6139 return rc;
6140 }
6141
6142 info = (struct dasd_ckd_host_information *)
6143 access->host_access_information;
6144 for (i = 0; i < info->entry_count; i++) {
6145 entry = (struct dasd_ckd_path_group_entry *)
6146 (info->entry + i * info->entry_size);
6147
6148 seq_printf(m, "pgid %*phN\n", 11, entry->pgid);
6149
6150 seq_printf(m, "status_flags %02x\n", entry->status_flags);
6151
6152 memcpy(&sysplex, &entry->sysplex_name, sizeof(sysplex) - 1);
6153 EBCASC(sysplex, sizeof(sysplex));
6154 seq_printf(m, "sysplex_name %8s\n", sysplex);
6155
6156 seq_printf(m, "supported_cylinder %d\n", entry->cylinder);
6157
6158 seq_printf(m, "timestamp %lu\n", (unsigned long)
6159 entry->timestamp);
6160 }
6161 kfree(access);
6162
6163 return 0;
6164}
6165
6166
6167
6168
6169static int
6170dasd_eckd_psf_cuir_response(struct dasd_device *device, int response,
6171 __u32 message_id, __u8 lpum)
6172{
6173 struct dasd_psf_cuir_response *psf_cuir;
6174 int pos = pathmask_to_pos(lpum);
6175 struct dasd_ccw_req *cqr;
6176 struct ccw1 *ccw;
6177 int rc;
6178
6179 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 ,
6180 sizeof(struct dasd_psf_cuir_response),
6181 device, NULL);
6182
6183 if (IS_ERR(cqr)) {
6184 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
6185 "Could not allocate PSF-CUIR request");
6186 return PTR_ERR(cqr);
6187 }
6188
6189 psf_cuir = (struct dasd_psf_cuir_response *)cqr->data;
6190 psf_cuir->order = PSF_ORDER_CUIR_RESPONSE;
6191 psf_cuir->cc = response;
6192 psf_cuir->chpid = device->path[pos].chpid;
6193 psf_cuir->message_id = message_id;
6194 psf_cuir->cssid = device->path[pos].cssid;
6195 psf_cuir->ssid = device->path[pos].ssid;
6196 ccw = cqr->cpaddr;
6197 ccw->cmd_code = DASD_ECKD_CCW_PSF;
6198 ccw->cda = (__u32)(addr_t)psf_cuir;
6199 ccw->flags = CCW_FLAG_SLI;
6200 ccw->count = sizeof(struct dasd_psf_cuir_response);
6201
6202 cqr->startdev = device;
6203 cqr->memdev = device;
6204 cqr->block = NULL;
6205 cqr->retries = 256;
6206 cqr->expires = 10*HZ;
6207 cqr->buildclk = get_tod_clock();
6208 cqr->status = DASD_CQR_FILLED;
6209 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
6210
6211 rc = dasd_sleep_on(cqr);
6212
6213 dasd_sfree_request(cqr, cqr->memdev);
6214 return rc;
6215}
6216
6217
6218
6219
6220
6221
6222static struct dasd_conf_data *dasd_eckd_get_ref_conf(struct dasd_device *device,
6223 __u8 lpum,
6224 struct dasd_cuir_message *cuir)
6225{
6226 struct dasd_conf_data *conf_data;
6227 int path, pos;
6228
6229 if (cuir->record_selector == 0)
6230 goto out;
6231 for (path = 0x80, pos = 0; path; path >>= 1, pos++) {
6232 conf_data = device->path[pos].conf_data;
6233 if (conf_data->gneq.record_selector ==
6234 cuir->record_selector)
6235 return conf_data;
6236 }
6237out:
6238 return device->path[pathmask_to_pos(lpum)].conf_data;
6239}
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250static int dasd_eckd_cuir_scope(struct dasd_device *device, __u8 lpum,
6251 struct dasd_cuir_message *cuir)
6252{
6253 struct dasd_conf_data *ref_conf_data;
6254 unsigned long bitmask = 0, mask = 0;
6255 struct dasd_conf_data *conf_data;
6256 unsigned int pos, path;
6257 char *ref_gneq, *gneq;
6258 char *ref_ned, *ned;
6259 int tbcpm = 0;
6260
6261
6262
6263 if (!cuir->ned_map ||
6264 !(cuir->neq_map[0] | cuir->neq_map[1] | cuir->neq_map[2]))
6265 return lpum;
6266
6267
6268 ref_conf_data = dasd_eckd_get_ref_conf(device, lpum, cuir);
6269
6270 pos = 8 - ffs(cuir->ned_map);
6271 ref_ned = (char *)&ref_conf_data->neds[pos];
6272 ref_gneq = (char *)&ref_conf_data->gneq;
6273
6274 mask = cuir->neq_map[2];
6275 mask |= cuir->neq_map[1] << 8;
6276 mask |= cuir->neq_map[0] << 16;
6277
6278 for (path = 0; path < 8; path++) {
6279
6280 bitmask = mask;
6281 conf_data = device->path[path].conf_data;
6282 pos = 8 - ffs(cuir->ned_map);
6283 ned = (char *) &conf_data->neds[pos];
6284
6285 if (memcmp(ref_ned, ned, sizeof(*ned)) != 0)
6286 continue;
6287 gneq = (char *)&conf_data->gneq;
6288
6289
6290
6291 while (bitmask) {
6292 pos = ffs(bitmask) - 1;
6293 if (memcmp(&ref_gneq[31 - pos], &gneq[31 - pos], 1)
6294 != 0)
6295 break;
6296 clear_bit(pos, &bitmask);
6297 }
6298 if (bitmask)
6299 continue;
6300
6301
6302 tbcpm |= 0x80 >> path;
6303 }
6304 return tbcpm;
6305}
6306
6307static void dasd_eckd_cuir_notify_user(struct dasd_device *device,
6308 unsigned long paths, int action)
6309{
6310 int pos;
6311
6312 while (paths) {
6313
6314 pos = 8 - ffs(paths);
6315
6316 if (action == CUIR_QUIESCE)
6317 pr_warn("Service on the storage server caused path %x.%02x to go offline",
6318 device->path[pos].cssid,
6319 device->path[pos].chpid);
6320 else if (action == CUIR_RESUME)
6321 pr_info("Path %x.%02x is back online after service on the storage server",
6322 device->path[pos].cssid,
6323 device->path[pos].chpid);
6324 clear_bit(7 - pos, &paths);
6325 }
6326}
6327
6328static int dasd_eckd_cuir_remove_path(struct dasd_device *device, __u8 lpum,
6329 struct dasd_cuir_message *cuir)
6330{
6331 unsigned long tbcpm;
6332
6333 tbcpm = dasd_eckd_cuir_scope(device, lpum, cuir);
6334
6335 if (!(dasd_path_get_opm(device) & tbcpm))
6336 return 0;
6337 if (!(dasd_path_get_opm(device) & ~tbcpm)) {
6338
6339
6340 return -EINVAL;
6341 }
6342
6343 dasd_path_remove_opm(device, tbcpm);
6344 dasd_path_add_cuirpm(device, tbcpm);
6345 return tbcpm;
6346}
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356static int dasd_eckd_cuir_quiesce(struct dasd_device *device, __u8 lpum,
6357 struct dasd_cuir_message *cuir)
6358{
6359 struct dasd_eckd_private *private = device->private;
6360 struct alias_pav_group *pavgroup, *tempgroup;
6361 struct dasd_device *dev, *n;
6362 unsigned long paths = 0;
6363 unsigned long flags;
6364 int tbcpm;
6365
6366
6367 list_for_each_entry_safe(dev, n, &private->lcu->active_devices,
6368 alias_list) {
6369 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);
6370 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);
6371 spin_unlock_irqrestore(get_ccwdev_lock(dev->cdev), flags);
6372 if (tbcpm < 0)
6373 goto out_err;
6374 paths |= tbcpm;
6375 }
6376
6377 list_for_each_entry_safe(dev, n, &private->lcu->inactive_devices,
6378 alias_list) {
6379 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);
6380 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);
6381 spin_unlock_irqrestore(get_ccwdev_lock(dev->cdev), flags);
6382 if (tbcpm < 0)
6383 goto out_err;
6384 paths |= tbcpm;
6385 }
6386
6387 list_for_each_entry_safe(pavgroup, tempgroup,
6388 &private->lcu->grouplist, group) {
6389 list_for_each_entry_safe(dev, n, &pavgroup->baselist,
6390 alias_list) {
6391 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);
6392 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);
6393 spin_unlock_irqrestore(
6394 get_ccwdev_lock(dev->cdev), flags);
6395 if (tbcpm < 0)
6396 goto out_err;
6397 paths |= tbcpm;
6398 }
6399 list_for_each_entry_safe(dev, n, &pavgroup->aliaslist,
6400 alias_list) {
6401 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);
6402 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);
6403 spin_unlock_irqrestore(
6404 get_ccwdev_lock(dev->cdev), flags);
6405 if (tbcpm < 0)
6406 goto out_err;
6407 paths |= tbcpm;
6408 }
6409 }
6410
6411 dasd_eckd_cuir_notify_user(device, paths, CUIR_QUIESCE);
6412 return 0;
6413out_err:
6414 return tbcpm;
6415}
6416
6417static int dasd_eckd_cuir_resume(struct dasd_device *device, __u8 lpum,
6418 struct dasd_cuir_message *cuir)
6419{
6420 struct dasd_eckd_private *private = device->private;
6421 struct alias_pav_group *pavgroup, *tempgroup;
6422 struct dasd_device *dev, *n;
6423 unsigned long paths = 0;
6424 int tbcpm;
6425
6426
6427
6428
6429
6430 list_for_each_entry_safe(dev, n,
6431 &private->lcu->active_devices,
6432 alias_list) {
6433 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);
6434 paths |= tbcpm;
6435 if (!(dasd_path_get_opm(dev) & tbcpm)) {
6436 dasd_path_add_tbvpm(dev, tbcpm);
6437 dasd_schedule_device_bh(dev);
6438 }
6439 }
6440 list_for_each_entry_safe(dev, n,
6441 &private->lcu->inactive_devices,
6442 alias_list) {
6443 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);
6444 paths |= tbcpm;
6445 if (!(dasd_path_get_opm(dev) & tbcpm)) {
6446 dasd_path_add_tbvpm(dev, tbcpm);
6447 dasd_schedule_device_bh(dev);
6448 }
6449 }
6450
6451 list_for_each_entry_safe(pavgroup, tempgroup,
6452 &private->lcu->grouplist,
6453 group) {
6454 list_for_each_entry_safe(dev, n,
6455 &pavgroup->baselist,
6456 alias_list) {
6457 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);
6458 paths |= tbcpm;
6459 if (!(dasd_path_get_opm(dev) & tbcpm)) {
6460 dasd_path_add_tbvpm(dev, tbcpm);
6461 dasd_schedule_device_bh(dev);
6462 }
6463 }
6464 list_for_each_entry_safe(dev, n,
6465 &pavgroup->aliaslist,
6466 alias_list) {
6467 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);
6468 paths |= tbcpm;
6469 if (!(dasd_path_get_opm(dev) & tbcpm)) {
6470 dasd_path_add_tbvpm(dev, tbcpm);
6471 dasd_schedule_device_bh(dev);
6472 }
6473 }
6474 }
6475
6476 dasd_eckd_cuir_notify_user(device, paths, CUIR_RESUME);
6477 return 0;
6478}
6479
6480static void dasd_eckd_handle_cuir(struct dasd_device *device, void *messages,
6481 __u8 lpum)
6482{
6483 struct dasd_cuir_message *cuir = messages;
6484 int response;
6485
6486 DBF_DEV_EVENT(DBF_WARNING, device,
6487 "CUIR request: %016llx %016llx %016llx %08x",
6488 ((u64 *)cuir)[0], ((u64 *)cuir)[1], ((u64 *)cuir)[2],
6489 ((u32 *)cuir)[3]);
6490
6491 if (cuir->code == CUIR_QUIESCE) {
6492
6493 if (dasd_eckd_cuir_quiesce(device, lpum, cuir))
6494 response = PSF_CUIR_LAST_PATH;
6495 else
6496 response = PSF_CUIR_COMPLETED;
6497 } else if (cuir->code == CUIR_RESUME) {
6498
6499 dasd_eckd_cuir_resume(device, lpum, cuir);
6500 response = PSF_CUIR_COMPLETED;
6501 } else
6502 response = PSF_CUIR_NOT_SUPPORTED;
6503
6504 dasd_eckd_psf_cuir_response(device, response,
6505 cuir->message_id, lpum);
6506 DBF_DEV_EVENT(DBF_WARNING, device,
6507 "CUIR response: %d on message ID %08x", response,
6508 cuir->message_id);
6509
6510 device->discipline->check_attention(device, lpum);
6511}
6512
6513static void dasd_eckd_oos_resume(struct dasd_device *device)
6514{
6515 struct dasd_eckd_private *private = device->private;
6516 struct alias_pav_group *pavgroup, *tempgroup;
6517 struct dasd_device *dev, *n;
6518 unsigned long flags;
6519
6520 spin_lock_irqsave(&private->lcu->lock, flags);
6521 list_for_each_entry_safe(dev, n, &private->lcu->active_devices,
6522 alias_list) {
6523 if (dev->stopped & DASD_STOPPED_NOSPC)
6524 dasd_generic_space_avail(dev);
6525 }
6526 list_for_each_entry_safe(dev, n, &private->lcu->inactive_devices,
6527 alias_list) {
6528 if (dev->stopped & DASD_STOPPED_NOSPC)
6529 dasd_generic_space_avail(dev);
6530 }
6531
6532 list_for_each_entry_safe(pavgroup, tempgroup,
6533 &private->lcu->grouplist,
6534 group) {
6535 list_for_each_entry_safe(dev, n, &pavgroup->baselist,
6536 alias_list) {
6537 if (dev->stopped & DASD_STOPPED_NOSPC)
6538 dasd_generic_space_avail(dev);
6539 }
6540 list_for_each_entry_safe(dev, n, &pavgroup->aliaslist,
6541 alias_list) {
6542 if (dev->stopped & DASD_STOPPED_NOSPC)
6543 dasd_generic_space_avail(dev);
6544 }
6545 }
6546 spin_unlock_irqrestore(&private->lcu->lock, flags);
6547}
6548
6549static void dasd_eckd_handle_oos(struct dasd_device *device, void *messages,
6550 __u8 lpum)
6551{
6552 struct dasd_oos_message *oos = messages;
6553
6554 switch (oos->code) {
6555 case REPO_WARN:
6556 case POOL_WARN:
6557 dev_warn(&device->cdev->dev,
6558 "Extent pool usage has reached a critical value\n");
6559 dasd_eckd_oos_resume(device);
6560 break;
6561 case REPO_EXHAUST:
6562 case POOL_EXHAUST:
6563 dev_warn(&device->cdev->dev,
6564 "Extent pool is exhausted\n");
6565 break;
6566 case REPO_RELIEVE:
6567 case POOL_RELIEVE:
6568 dev_info(&device->cdev->dev,
6569 "Extent pool physical space constraint has been relieved\n");
6570 break;
6571 }
6572
6573
6574 dasd_eckd_read_ext_pool_info(device);
6575
6576
6577 device->discipline->check_attention(device, lpum);
6578}
6579
6580static void dasd_eckd_check_attention_work(struct work_struct *work)
6581{
6582 struct check_attention_work_data *data;
6583 struct dasd_rssd_messages *messages;
6584 struct dasd_device *device;
6585 int rc;
6586
6587 data = container_of(work, struct check_attention_work_data, worker);
6588 device = data->device;
6589 messages = kzalloc(sizeof(*messages), GFP_KERNEL);
6590 if (!messages) {
6591 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
6592 "Could not allocate attention message buffer");
6593 goto out;
6594 }
6595 rc = dasd_eckd_read_message_buffer(device, messages, data->lpum);
6596 if (rc)
6597 goto out;
6598
6599 if (messages->length == ATTENTION_LENGTH_CUIR &&
6600 messages->format == ATTENTION_FORMAT_CUIR)
6601 dasd_eckd_handle_cuir(device, messages, data->lpum);
6602 if (messages->length == ATTENTION_LENGTH_OOS &&
6603 messages->format == ATTENTION_FORMAT_OOS)
6604 dasd_eckd_handle_oos(device, messages, data->lpum);
6605
6606out:
6607 dasd_put_device(device);
6608 kfree(messages);
6609 kfree(data);
6610}
6611
6612static int dasd_eckd_check_attention(struct dasd_device *device, __u8 lpum)
6613{
6614 struct check_attention_work_data *data;
6615
6616 data = kzalloc(sizeof(*data), GFP_ATOMIC);
6617 if (!data)
6618 return -ENOMEM;
6619 INIT_WORK(&data->worker, dasd_eckd_check_attention_work);
6620 dasd_get_device(device);
6621 data->device = device;
6622 data->lpum = lpum;
6623 schedule_work(&data->worker);
6624 return 0;
6625}
6626
6627static int dasd_eckd_disable_hpf_path(struct dasd_device *device, __u8 lpum)
6628{
6629 if (~lpum & dasd_path_get_opm(device)) {
6630 dasd_path_add_nohpfpm(device, lpum);
6631 dasd_path_remove_opm(device, lpum);
6632 dev_err(&device->cdev->dev,
6633 "Channel path %02X lost HPF functionality and is disabled\n",
6634 lpum);
6635 return 1;
6636 }
6637 return 0;
6638}
6639
6640static void dasd_eckd_disable_hpf_device(struct dasd_device *device)
6641{
6642 struct dasd_eckd_private *private = device->private;
6643
6644 dev_err(&device->cdev->dev,
6645 "High Performance FICON disabled\n");
6646 private->fcx_max_data = 0;
6647}
6648
6649static int dasd_eckd_hpf_enabled(struct dasd_device *device)
6650{
6651 struct dasd_eckd_private *private = device->private;
6652
6653 return private->fcx_max_data ? 1 : 0;
6654}
6655
6656static void dasd_eckd_handle_hpf_error(struct dasd_device *device,
6657 struct irb *irb)
6658{
6659 struct dasd_eckd_private *private = device->private;
6660
6661 if (!private->fcx_max_data) {
6662
6663 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
6664 "Trying to disable HPF for a non HPF device");
6665 return;
6666 }
6667 if (irb->scsw.tm.sesq == SCSW_SESQ_DEV_NOFCX) {
6668 dasd_eckd_disable_hpf_device(device);
6669 } else if (irb->scsw.tm.sesq == SCSW_SESQ_PATH_NOFCX) {
6670 if (dasd_eckd_disable_hpf_path(device, irb->esw.esw1.lpum))
6671 return;
6672 dasd_eckd_disable_hpf_device(device);
6673 dasd_path_set_tbvpm(device,
6674 dasd_path_get_hpfpm(device));
6675 }
6676
6677
6678
6679
6680 dasd_device_set_stop_bits(device, DASD_STOPPED_NOT_ACC);
6681 dasd_schedule_requeue(device);
6682}
6683
6684
6685
6686
6687static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
6688{
6689 unsigned int logical_block_size = block->bp_block;
6690 struct request_queue *q = block->request_queue;
6691 struct dasd_device *device = block->base;
6692 int max;
6693
6694 if (device->features & DASD_FEATURE_USERAW) {
6695
6696
6697
6698
6699
6700
6701
6702 max = DASD_ECKD_MAX_BLOCKS_RAW << block->s2b_shift;
6703 } else {
6704 max = DASD_ECKD_MAX_BLOCKS << block->s2b_shift;
6705 }
6706 blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
6707 q->limits.max_dev_sectors = max;
6708 blk_queue_logical_block_size(q, logical_block_size);
6709 blk_queue_max_hw_sectors(q, max);
6710 blk_queue_max_segments(q, USHRT_MAX);
6711
6712 blk_queue_max_segment_size(q, PAGE_SIZE);
6713 blk_queue_segment_boundary(q, PAGE_SIZE - 1);
6714}
6715
6716static struct ccw_driver dasd_eckd_driver = {
6717 .driver = {
6718 .name = "dasd-eckd",
6719 .owner = THIS_MODULE,
6720 },
6721 .ids = dasd_eckd_ids,
6722 .probe = dasd_eckd_probe,
6723 .remove = dasd_generic_remove,
6724 .set_offline = dasd_generic_set_offline,
6725 .set_online = dasd_eckd_set_online,
6726 .notify = dasd_generic_notify,
6727 .path_event = dasd_generic_path_event,
6728 .shutdown = dasd_generic_shutdown,
6729 .freeze = dasd_generic_pm_freeze,
6730 .thaw = dasd_generic_restore_device,
6731 .restore = dasd_generic_restore_device,
6732 .uc_handler = dasd_generic_uc_handler,
6733 .int_class = IRQIO_DAS,
6734};
6735
6736static struct dasd_discipline dasd_eckd_discipline = {
6737 .owner = THIS_MODULE,
6738 .name = "ECKD",
6739 .ebcname = "ECKD",
6740 .check_device = dasd_eckd_check_characteristics,
6741 .uncheck_device = dasd_eckd_uncheck_device,
6742 .do_analysis = dasd_eckd_do_analysis,
6743 .pe_handler = dasd_eckd_pe_handler,
6744 .basic_to_ready = dasd_eckd_basic_to_ready,
6745 .online_to_ready = dasd_eckd_online_to_ready,
6746 .basic_to_known = dasd_eckd_basic_to_known,
6747 .setup_blk_queue = dasd_eckd_setup_blk_queue,
6748 .fill_geometry = dasd_eckd_fill_geometry,
6749 .start_IO = dasd_start_IO,
6750 .term_IO = dasd_term_IO,
6751 .handle_terminated_request = dasd_eckd_handle_terminated_request,
6752 .format_device = dasd_eckd_format_device,
6753 .check_device_format = dasd_eckd_check_device_format,
6754 .erp_action = dasd_eckd_erp_action,
6755 .erp_postaction = dasd_eckd_erp_postaction,
6756 .check_for_device_change = dasd_eckd_check_for_device_change,
6757 .build_cp = dasd_eckd_build_alias_cp,
6758 .free_cp = dasd_eckd_free_alias_cp,
6759 .dump_sense = dasd_eckd_dump_sense,
6760 .dump_sense_dbf = dasd_eckd_dump_sense_dbf,
6761 .fill_info = dasd_eckd_fill_info,
6762 .ioctl = dasd_eckd_ioctl,
6763 .freeze = dasd_eckd_pm_freeze,
6764 .restore = dasd_eckd_restore_device,
6765 .reload = dasd_eckd_reload_device,
6766 .get_uid = dasd_eckd_get_uid,
6767 .kick_validate = dasd_eckd_kick_validate_server,
6768 .check_attention = dasd_eckd_check_attention,
6769 .host_access_count = dasd_eckd_host_access_count,
6770 .hosts_print = dasd_hosts_print,
6771 .handle_hpf_error = dasd_eckd_handle_hpf_error,
6772 .disable_hpf = dasd_eckd_disable_hpf_device,
6773 .hpf_enabled = dasd_eckd_hpf_enabled,
6774 .reset_path = dasd_eckd_reset_path,
6775 .is_ese = dasd_eckd_is_ese,
6776 .space_allocated = dasd_eckd_space_allocated,
6777 .space_configured = dasd_eckd_space_configured,
6778 .logical_capacity = dasd_eckd_logical_capacity,
6779 .release_space = dasd_eckd_release_space,
6780 .ext_pool_id = dasd_eckd_ext_pool_id,
6781 .ext_size = dasd_eckd_ext_size,
6782 .ext_pool_cap_at_warnlevel = dasd_eckd_ext_pool_cap_at_warnlevel,
6783 .ext_pool_warn_thrshld = dasd_eckd_ext_pool_warn_thrshld,
6784 .ext_pool_oos = dasd_eckd_ext_pool_oos,
6785 .ext_pool_exhaust = dasd_eckd_ext_pool_exhaust,
6786 .ese_format = dasd_eckd_ese_format,
6787 .ese_read = dasd_eckd_ese_read,
6788};
6789
6790static int __init
6791dasd_eckd_init(void)
6792{
6793 int ret;
6794
6795 ASCEBC(dasd_eckd_discipline.ebcname, 4);
6796 dasd_reserve_req = kmalloc(sizeof(*dasd_reserve_req),
6797 GFP_KERNEL | GFP_DMA);
6798 if (!dasd_reserve_req)
6799 return -ENOMEM;
6800 dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req),
6801 GFP_KERNEL | GFP_DMA);
6802 if (!dasd_vol_info_req)
6803 return -ENOMEM;
6804 pe_handler_worker = kmalloc(sizeof(*pe_handler_worker),
6805 GFP_KERNEL | GFP_DMA);
6806 if (!pe_handler_worker) {
6807 kfree(dasd_reserve_req);
6808 kfree(dasd_vol_info_req);
6809 return -ENOMEM;
6810 }
6811 rawpadpage = (void *)__get_free_page(GFP_KERNEL);
6812 if (!rawpadpage) {
6813 kfree(pe_handler_worker);
6814 kfree(dasd_reserve_req);
6815 kfree(dasd_vol_info_req);
6816 return -ENOMEM;
6817 }
6818 ret = ccw_driver_register(&dasd_eckd_driver);
6819 if (!ret)
6820 wait_for_device_probe();
6821 else {
6822 kfree(pe_handler_worker);
6823 kfree(dasd_reserve_req);
6824 kfree(dasd_vol_info_req);
6825 free_page((unsigned long)rawpadpage);
6826 }
6827 return ret;
6828}
6829
6830static void __exit
6831dasd_eckd_cleanup(void)
6832{
6833 ccw_driver_unregister(&dasd_eckd_driver);
6834 kfree(pe_handler_worker);
6835 kfree(dasd_reserve_req);
6836 free_page((unsigned long)rawpadpage);
6837}
6838
6839module_init(dasd_eckd_init);
6840module_exit(dasd_eckd_cleanup);
6841