[S390] dasd: add High Performance FICON support
[linux-block.git] / drivers / s390 / block / dasd_eckd.c
CommitLineData
138c014d 1/*
1da177e4
LT
2 * File...........: linux/drivers/s390/block/dasd_eckd.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
138c014d 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
1da177e4
LT
5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com>
8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
ab1d848f
NH
9 * EMC Symmetrix ioctl Copyright EMC Corporation, 2008
10 * Author.........: Nigel Hislop <hislop_nigel@emc.com>
1da177e4 11 *
1da177e4
LT
12 */
13
1da177e4
LT
14#include <linux/stddef.h>
15#include <linux/kernel.h>
16#include <linux/slab.h>
17#include <linux/hdreg.h> /* HDIO_GETGEO */
18#include <linux/bio.h>
19#include <linux/module.h>
20#include <linux/init.h>
21
22#include <asm/debug.h>
23#include <asm/idals.h>
24#include <asm/ebcdic.h>
25#include <asm/io.h>
26#include <asm/todclk.h>
27#include <asm/uaccess.h>
40545573 28#include <asm/cio.h>
1da177e4 29#include <asm/ccwdev.h>
f3eb5384 30#include <asm/itcw.h>
1da177e4
LT
31
32#include "dasd_int.h"
33#include "dasd_eckd.h"
f3eb5384
SW
34#include "../cio/chsc.h"
35
1da177e4
LT
36
37#ifdef PRINTK_HEADER
38#undef PRINTK_HEADER
39#endif /* PRINTK_HEADER */
40#define PRINTK_HEADER "dasd(eckd):"
41
42#define ECKD_C0(i) (i->home_bytes)
43#define ECKD_F(i) (i->formula)
44#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):\
45 (i->factors.f_0x02.f1))
46#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):\
47 (i->factors.f_0x02.f2))
48#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):\
49 (i->factors.f_0x02.f3))
50#define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0)
51#define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0)
52#define ECKD_F6(i) (i->factor6)
53#define ECKD_F7(i) (i->factor7)
54#define ECKD_F8(i) (i->factor8)
55
56MODULE_LICENSE("GPL");
57
58static struct dasd_discipline dasd_eckd_discipline;
59
1da177e4
LT
60/* The ccw bus type uses this table to find devices that it sends to
61 * dasd_eckd_probe */
62static struct ccw_device_id dasd_eckd_ids[] = {
d2c993d8
HC
63 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1},
64 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2},
65 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), .driver_info = 0x3},
66 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4},
67 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5},
68 { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6},
69 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3390, 0), .driver_info = 0x7},
70 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3380, 0), .driver_info = 0x8},
71 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3390, 0), .driver_info = 0x9},
72 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3380, 0), .driver_info = 0xa},
1da177e4
LT
73 { /* end of list */ },
74};
75
76MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);
77
78static struct ccw_driver dasd_eckd_driver; /* see below */
79
80/* initial attempt at a probe function. this can be simplified once
81 * the other detection code is gone */
82static int
83dasd_eckd_probe (struct ccw_device *cdev)
84{
85 int ret;
86
40545573
HH
87 /* set ECKD specific ccw-device options */
88 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
89 if (ret) {
90 printk(KERN_WARNING
91 "dasd_eckd_probe: could not set ccw-device options "
2a0217d5 92 "for %s\n", dev_name(&cdev->dev));
1da177e4 93 return ret;
40545573
HH
94 }
95 ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
96 return ret;
1da177e4
LT
97}
98
99static int
100dasd_eckd_set_online(struct ccw_device *cdev)
101{
40545573 102 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
1da177e4
LT
103}
104
105static struct ccw_driver dasd_eckd_driver = {
106 .name = "dasd-eckd",
107 .owner = THIS_MODULE,
108 .ids = dasd_eckd_ids,
109 .probe = dasd_eckd_probe,
110 .remove = dasd_generic_remove,
111 .set_offline = dasd_generic_set_offline,
112 .set_online = dasd_eckd_set_online,
113 .notify = dasd_generic_notify,
114};
115
116static const int sizes_trk0[] = { 28, 148, 84 };
117#define LABEL_SIZE 140
118
119static inline unsigned int
120round_up_multiple(unsigned int no, unsigned int mult)
121{
122 int rem = no % mult;
123 return (rem ? no - rem + mult : no);
124}
125
126static inline unsigned int
127ceil_quot(unsigned int d1, unsigned int d2)
128{
129 return (d1 + (d2 - 1)) / d2;
130}
131
4d284cac 132static unsigned int
1da177e4
LT
133recs_per_track(struct dasd_eckd_characteristics * rdc,
134 unsigned int kl, unsigned int dl)
135{
136 int dn, kn;
137
138 switch (rdc->dev_type) {
139 case 0x3380:
140 if (kl)
141 return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) +
142 ceil_quot(dl + 12, 32));
143 else
144 return 1499 / (15 + ceil_quot(dl + 12, 32));
145 case 0x3390:
146 dn = ceil_quot(dl + 6, 232) + 1;
147 if (kl) {
148 kn = ceil_quot(kl + 6, 232) + 1;
149 return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
150 9 + ceil_quot(dl + 6 * dn, 34));
151 } else
152 return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
153 case 0x9345:
154 dn = ceil_quot(dl + 6, 232) + 1;
155 if (kl) {
156 kn = ceil_quot(kl + 6, 232) + 1;
157 return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) +
158 ceil_quot(dl + 6 * dn, 34));
159 } else
160 return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34));
161 }
162 return 0;
163}
164
b44b0ab3
SW
165static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
166{
167 geo->cyl = (__u16) cyl;
168 geo->head = cyl >> 16;
169 geo->head <<= 4;
170 geo->head |= head;
171}
172
4d284cac 173static int
1da177e4
LT
174check_XRC (struct ccw1 *de_ccw,
175 struct DE_eckd_data *data,
176 struct dasd_device *device)
177{
178 struct dasd_eckd_private *private;
d54853ef 179 int rc;
1da177e4
LT
180
181 private = (struct dasd_eckd_private *) device->private;
d54853ef
MS
182 if (!private->rdc_data.facilities.XRC_supported)
183 return 0;
1da177e4
LT
184
185 /* switch on System Time Stamp - needed for XRC Support */
d54853ef
MS
186 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
187 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
1da177e4 188
d54853ef
MS
189 rc = get_sync_clock(&data->ep_sys_time);
190 /* Ignore return code if sync clock is switched off. */
191 if (rc == -ENOSYS || rc == -EACCES)
192 rc = 0;
1da177e4 193
8e09f215 194 de_ccw->count = sizeof(struct DE_eckd_data);
d54853ef
MS
195 de_ccw->flags |= CCW_FLAG_SLI;
196 return rc;
197}
1da177e4 198
4d284cac 199static int
b44b0ab3
SW
200define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
201 unsigned int totrk, int cmd, struct dasd_device *device)
1da177e4
LT
202{
203 struct dasd_eckd_private *private;
b44b0ab3
SW
204 u32 begcyl, endcyl;
205 u16 heads, beghead, endhead;
d54853ef 206 int rc = 0;
1da177e4
LT
207
208 private = (struct dasd_eckd_private *) device->private;
209
210 ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
211 ccw->flags = 0;
212 ccw->count = 16;
213 ccw->cda = (__u32) __pa(data);
214
8e09f215 215 memset(data, 0, sizeof(struct DE_eckd_data));
1da177e4
LT
216 switch (cmd) {
217 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
218 case DASD_ECKD_CCW_READ_RECORD_ZERO:
219 case DASD_ECKD_CCW_READ:
220 case DASD_ECKD_CCW_READ_MT:
221 case DASD_ECKD_CCW_READ_CKD:
222 case DASD_ECKD_CCW_READ_CKD_MT:
223 case DASD_ECKD_CCW_READ_KD:
224 case DASD_ECKD_CCW_READ_KD_MT:
225 case DASD_ECKD_CCW_READ_COUNT:
226 data->mask.perm = 0x1;
227 data->attributes.operation = private->attrib.operation;
228 break;
229 case DASD_ECKD_CCW_WRITE:
230 case DASD_ECKD_CCW_WRITE_MT:
231 case DASD_ECKD_CCW_WRITE_KD:
232 case DASD_ECKD_CCW_WRITE_KD_MT:
233 data->mask.perm = 0x02;
234 data->attributes.operation = private->attrib.operation;
d54853ef 235 rc = check_XRC (ccw, data, device);
1da177e4
LT
236 break;
237 case DASD_ECKD_CCW_WRITE_CKD:
238 case DASD_ECKD_CCW_WRITE_CKD_MT:
239 data->attributes.operation = DASD_BYPASS_CACHE;
d54853ef 240 rc = check_XRC (ccw, data, device);
1da177e4
LT
241 break;
242 case DASD_ECKD_CCW_ERASE:
243 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
244 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
245 data->mask.perm = 0x3;
246 data->mask.auth = 0x1;
247 data->attributes.operation = DASD_BYPASS_CACHE;
d54853ef 248 rc = check_XRC (ccw, data, device);
1da177e4
LT
249 break;
250 default:
f3eb5384
SW
251 DBF_DEV_EVENT(DBF_ERR, device,
252 "PFX LRE unknown opcode 0x%x", cmd);
1da177e4
LT
253 break;
254 }
255
256 data->attributes.mode = 0x3; /* ECKD */
257
258 if ((private->rdc_data.cu_type == 0x2105 ||
259 private->rdc_data.cu_type == 0x2107 ||
260 private->rdc_data.cu_type == 0x1750)
261 && !(private->uses_cdl && trk < 2))
262 data->ga_extended |= 0x40; /* Regular Data Format Mode */
263
b44b0ab3
SW
264 heads = private->rdc_data.trk_per_cyl;
265 begcyl = trk / heads;
266 beghead = trk % heads;
267 endcyl = totrk / heads;
268 endhead = totrk % heads;
1da177e4
LT
269
270 /* check for sequential prestage - enhance cylinder range */
271 if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
272 data->attributes.operation == DASD_SEQ_ACCESS) {
138c014d 273
b44b0ab3
SW
274 if (endcyl + private->attrib.nr_cyl < private->real_cyl)
275 endcyl += private->attrib.nr_cyl;
1da177e4 276 else
b44b0ab3 277 endcyl = (private->real_cyl - 1);
1da177e4
LT
278 }
279
b44b0ab3
SW
280 set_ch_t(&data->beg_ext, begcyl, beghead);
281 set_ch_t(&data->end_ext, endcyl, endhead);
d54853ef 282 return rc;
1da177e4
LT
283}
284
8e09f215
SW
285static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
286 struct dasd_device *device)
287{
288 struct dasd_eckd_private *private;
289 int rc;
290
291 private = (struct dasd_eckd_private *) device->private;
292 if (!private->rdc_data.facilities.XRC_supported)
293 return 0;
294
295 /* switch on System Time Stamp - needed for XRC Support */
f3eb5384
SW
296 pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid' */
297 pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
8e09f215
SW
298 pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */
299
f3eb5384 300 rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
8e09f215
SW
301 /* Ignore return code if sync clock is switched off. */
302 if (rc == -ENOSYS || rc == -EACCES)
303 rc = 0;
304 return rc;
305}
306
f3eb5384
SW
307static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
308 unsigned int rec_on_trk, int count, int cmd,
309 struct dasd_device *device, unsigned int reclen,
310 unsigned int tlf)
311{
312 struct dasd_eckd_private *private;
313 int sector;
314 int dn, d;
315
316 private = (struct dasd_eckd_private *) device->private;
317
318 memset(data, 0, sizeof(*data));
319 sector = 0;
320 if (rec_on_trk) {
321 switch (private->rdc_data.dev_type) {
322 case 0x3390:
323 dn = ceil_quot(reclen + 6, 232);
324 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
325 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
326 break;
327 case 0x3380:
328 d = 7 + ceil_quot(reclen + 12, 32);
329 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
330 break;
331 }
332 }
333 data->sector = sector;
334 /* note: meaning of count depends on the operation
335 * for record based I/O it's the number of records, but for
336 * track based I/O it's the number of tracks
337 */
338 data->count = count;
339 switch (cmd) {
340 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
341 data->operation.orientation = 0x3;
342 data->operation.operation = 0x03;
343 break;
344 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
345 data->operation.orientation = 0x3;
346 data->operation.operation = 0x16;
347 break;
348 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
349 data->operation.orientation = 0x1;
350 data->operation.operation = 0x03;
351 data->count++;
352 break;
353 case DASD_ECKD_CCW_READ_RECORD_ZERO:
354 data->operation.orientation = 0x3;
355 data->operation.operation = 0x16;
356 data->count++;
357 break;
358 case DASD_ECKD_CCW_WRITE:
359 case DASD_ECKD_CCW_WRITE_MT:
360 case DASD_ECKD_CCW_WRITE_KD:
361 case DASD_ECKD_CCW_WRITE_KD_MT:
362 data->auxiliary.length_valid = 0x1;
363 data->length = reclen;
364 data->operation.operation = 0x01;
365 break;
366 case DASD_ECKD_CCW_WRITE_CKD:
367 case DASD_ECKD_CCW_WRITE_CKD_MT:
368 data->auxiliary.length_valid = 0x1;
369 data->length = reclen;
370 data->operation.operation = 0x03;
371 break;
372 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
373 data->auxiliary.length_valid = 0x1;
374 data->length = reclen; /* not tlf, as one might think */
375 data->operation.operation = 0x3F;
376 data->extended_operation = 0x23;
377 break;
378 case DASD_ECKD_CCW_READ:
379 case DASD_ECKD_CCW_READ_MT:
380 case DASD_ECKD_CCW_READ_KD:
381 case DASD_ECKD_CCW_READ_KD_MT:
382 data->auxiliary.length_valid = 0x1;
383 data->length = reclen;
384 data->operation.operation = 0x06;
385 break;
386 case DASD_ECKD_CCW_READ_CKD:
387 case DASD_ECKD_CCW_READ_CKD_MT:
388 data->auxiliary.length_valid = 0x1;
389 data->length = reclen;
390 data->operation.operation = 0x16;
391 break;
392 case DASD_ECKD_CCW_READ_COUNT:
393 data->operation.operation = 0x06;
394 break;
395 case DASD_ECKD_CCW_READ_TRACK_DATA:
396 data->auxiliary.length_valid = 0x1;
397 data->length = tlf;
398 data->operation.operation = 0x0C;
399 break;
400 case DASD_ECKD_CCW_ERASE:
401 data->length = reclen;
402 data->auxiliary.length_valid = 0x1;
403 data->operation.operation = 0x0b;
404 break;
405 default:
406 DBF_DEV_EVENT(DBF_ERR, device,
407 "fill LRE unknown opcode 0x%x", cmd);
408 BUG();
409 }
410 set_ch_t(&data->seek_addr,
411 trk / private->rdc_data.trk_per_cyl,
412 trk % private->rdc_data.trk_per_cyl);
413 data->search_arg.cyl = data->seek_addr.cyl;
414 data->search_arg.head = data->seek_addr.head;
415 data->search_arg.record = rec_on_trk;
416}
417
418static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
419 unsigned int trk, unsigned int totrk, int cmd,
420 struct dasd_device *basedev, struct dasd_device *startdev,
421 unsigned char format, unsigned int rec_on_trk, int count,
422 unsigned int blksize, unsigned int tlf)
8e09f215
SW
423{
424 struct dasd_eckd_private *basepriv, *startpriv;
f3eb5384
SW
425 struct DE_eckd_data *dedata;
426 struct LRE_eckd_data *lredata;
b44b0ab3
SW
427 u32 begcyl, endcyl;
428 u16 heads, beghead, endhead;
8e09f215
SW
429 int rc = 0;
430
431 basepriv = (struct dasd_eckd_private *) basedev->private;
432 startpriv = (struct dasd_eckd_private *) startdev->private;
f3eb5384
SW
433 dedata = &pfxdata->define_extent;
434 lredata = &pfxdata->locate_record;
8e09f215
SW
435
436 ccw->cmd_code = DASD_ECKD_CCW_PFX;
437 ccw->flags = 0;
438 ccw->count = sizeof(*pfxdata);
439 ccw->cda = (__u32) __pa(pfxdata);
440
441 memset(pfxdata, 0, sizeof(*pfxdata));
442 /* prefix data */
f3eb5384
SW
443 if (format > 1) {
444 DBF_DEV_EVENT(DBF_ERR, basedev,
445 "PFX LRE unknown format 0x%x", format);
446 BUG();
447 return -EINVAL;
448 }
449 pfxdata->format = format;
4abb08c2
SW
450 pfxdata->base_address = basepriv->ned->unit_addr;
451 pfxdata->base_lss = basepriv->ned->ID;
f3eb5384 452 pfxdata->validity.define_extent = 1;
8e09f215
SW
453
454 /* private uid is kept up to date, conf_data may be outdated */
455 if (startpriv->uid.type != UA_BASE_DEVICE) {
456 pfxdata->validity.verify_base = 1;
457 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
458 pfxdata->validity.hyper_pav = 1;
459 }
460
461 /* define extend data (mostly)*/
462 switch (cmd) {
463 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
464 case DASD_ECKD_CCW_READ_RECORD_ZERO:
465 case DASD_ECKD_CCW_READ:
466 case DASD_ECKD_CCW_READ_MT:
467 case DASD_ECKD_CCW_READ_CKD:
468 case DASD_ECKD_CCW_READ_CKD_MT:
469 case DASD_ECKD_CCW_READ_KD:
470 case DASD_ECKD_CCW_READ_KD_MT:
471 case DASD_ECKD_CCW_READ_COUNT:
f3eb5384
SW
472 dedata->mask.perm = 0x1;
473 dedata->attributes.operation = basepriv->attrib.operation;
474 break;
475 case DASD_ECKD_CCW_READ_TRACK_DATA:
476 dedata->mask.perm = 0x1;
477 dedata->attributes.operation = basepriv->attrib.operation;
478 dedata->blk_size = 0;
8e09f215
SW
479 break;
480 case DASD_ECKD_CCW_WRITE:
481 case DASD_ECKD_CCW_WRITE_MT:
482 case DASD_ECKD_CCW_WRITE_KD:
483 case DASD_ECKD_CCW_WRITE_KD_MT:
f3eb5384
SW
484 dedata->mask.perm = 0x02;
485 dedata->attributes.operation = basepriv->attrib.operation;
8e09f215
SW
486 rc = check_XRC_on_prefix(pfxdata, basedev);
487 break;
488 case DASD_ECKD_CCW_WRITE_CKD:
489 case DASD_ECKD_CCW_WRITE_CKD_MT:
f3eb5384 490 dedata->attributes.operation = DASD_BYPASS_CACHE;
8e09f215
SW
491 rc = check_XRC_on_prefix(pfxdata, basedev);
492 break;
493 case DASD_ECKD_CCW_ERASE:
494 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
495 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
f3eb5384
SW
496 dedata->mask.perm = 0x3;
497 dedata->mask.auth = 0x1;
498 dedata->attributes.operation = DASD_BYPASS_CACHE;
8e09f215
SW
499 rc = check_XRC_on_prefix(pfxdata, basedev);
500 break;
f3eb5384
SW
501 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
502 dedata->mask.perm = 0x02;
503 dedata->attributes.operation = basepriv->attrib.operation;
504 dedata->blk_size = blksize;
505 rc = check_XRC_on_prefix(pfxdata, basedev);
8e09f215 506 break;
f3eb5384
SW
507 default:
508 DBF_DEV_EVENT(DBF_ERR, basedev,
509 "PFX LRE unknown opcode 0x%x", cmd);
510 BUG();
511 return -EINVAL;
8e09f215
SW
512 }
513
f3eb5384 514 dedata->attributes.mode = 0x3; /* ECKD */
8e09f215
SW
515
516 if ((basepriv->rdc_data.cu_type == 0x2105 ||
517 basepriv->rdc_data.cu_type == 0x2107 ||
518 basepriv->rdc_data.cu_type == 0x1750)
519 && !(basepriv->uses_cdl && trk < 2))
f3eb5384 520 dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
8e09f215 521
b44b0ab3
SW
522 heads = basepriv->rdc_data.trk_per_cyl;
523 begcyl = trk / heads;
524 beghead = trk % heads;
525 endcyl = totrk / heads;
526 endhead = totrk % heads;
8e09f215
SW
527
528 /* check for sequential prestage - enhance cylinder range */
f3eb5384
SW
529 if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
530 dedata->attributes.operation == DASD_SEQ_ACCESS) {
8e09f215 531
b44b0ab3
SW
532 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
533 endcyl += basepriv->attrib.nr_cyl;
8e09f215 534 else
b44b0ab3 535 endcyl = (basepriv->real_cyl - 1);
8e09f215
SW
536 }
537
f3eb5384
SW
538 set_ch_t(&dedata->beg_ext, begcyl, beghead);
539 set_ch_t(&dedata->end_ext, endcyl, endhead);
540
541 if (format == 1) {
542 fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
543 basedev, blksize, tlf);
544 }
545
8e09f215
SW
546 return rc;
547}
548
f3eb5384
SW
549static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
550 unsigned int trk, unsigned int totrk, int cmd,
551 struct dasd_device *basedev, struct dasd_device *startdev)
552{
553 return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
554 0, 0, 0, 0, 0);
555}
556
4d284cac 557static void
b44b0ab3
SW
558locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
559 unsigned int rec_on_trk, int no_rec, int cmd,
1da177e4
LT
560 struct dasd_device * device, int reclen)
561{
562 struct dasd_eckd_private *private;
563 int sector;
564 int dn, d;
138c014d 565
1da177e4
LT
566 private = (struct dasd_eckd_private *) device->private;
567
568 DBF_DEV_EVENT(DBF_INFO, device,
569 "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",
570 trk, rec_on_trk, no_rec, cmd, reclen);
571
572 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
573 ccw->flags = 0;
574 ccw->count = 16;
575 ccw->cda = (__u32) __pa(data);
576
8e09f215 577 memset(data, 0, sizeof(struct LO_eckd_data));
1da177e4
LT
578 sector = 0;
579 if (rec_on_trk) {
580 switch (private->rdc_data.dev_type) {
581 case 0x3390:
582 dn = ceil_quot(reclen + 6, 232);
583 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
584 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
585 break;
586 case 0x3380:
587 d = 7 + ceil_quot(reclen + 12, 32);
588 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
589 break;
590 }
591 }
592 data->sector = sector;
593 data->count = no_rec;
594 switch (cmd) {
595 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
596 data->operation.orientation = 0x3;
597 data->operation.operation = 0x03;
598 break;
599 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
600 data->operation.orientation = 0x3;
601 data->operation.operation = 0x16;
602 break;
603 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
604 data->operation.orientation = 0x1;
605 data->operation.operation = 0x03;
606 data->count++;
607 break;
608 case DASD_ECKD_CCW_READ_RECORD_ZERO:
609 data->operation.orientation = 0x3;
610 data->operation.operation = 0x16;
611 data->count++;
612 break;
613 case DASD_ECKD_CCW_WRITE:
614 case DASD_ECKD_CCW_WRITE_MT:
615 case DASD_ECKD_CCW_WRITE_KD:
616 case DASD_ECKD_CCW_WRITE_KD_MT:
617 data->auxiliary.last_bytes_used = 0x1;
618 data->length = reclen;
619 data->operation.operation = 0x01;
620 break;
621 case DASD_ECKD_CCW_WRITE_CKD:
622 case DASD_ECKD_CCW_WRITE_CKD_MT:
623 data->auxiliary.last_bytes_used = 0x1;
624 data->length = reclen;
625 data->operation.operation = 0x03;
626 break;
627 case DASD_ECKD_CCW_READ:
628 case DASD_ECKD_CCW_READ_MT:
629 case DASD_ECKD_CCW_READ_KD:
630 case DASD_ECKD_CCW_READ_KD_MT:
631 data->auxiliary.last_bytes_used = 0x1;
632 data->length = reclen;
633 data->operation.operation = 0x06;
634 break;
635 case DASD_ECKD_CCW_READ_CKD:
636 case DASD_ECKD_CCW_READ_CKD_MT:
637 data->auxiliary.last_bytes_used = 0x1;
638 data->length = reclen;
639 data->operation.operation = 0x16;
640 break;
641 case DASD_ECKD_CCW_READ_COUNT:
642 data->operation.operation = 0x06;
643 break;
644 case DASD_ECKD_CCW_ERASE:
645 data->length = reclen;
646 data->auxiliary.last_bytes_used = 0x1;
647 data->operation.operation = 0x0b;
648 break;
649 default:
650 DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
651 }
b44b0ab3
SW
652 set_ch_t(&data->seek_addr,
653 trk / private->rdc_data.trk_per_cyl,
654 trk % private->rdc_data.trk_per_cyl);
655 data->search_arg.cyl = data->seek_addr.cyl;
656 data->search_arg.head = data->seek_addr.head;
1da177e4
LT
657 data->search_arg.record = rec_on_trk;
658}
659
660/*
661 * Returns 1 if the block is one of the special blocks that needs
662 * to get read/written with the KD variant of the command.
663 * That is DASD_ECKD_READ_KD_MT instead of DASD_ECKD_READ_MT and
664 * DASD_ECKD_WRITE_KD_MT instead of DASD_ECKD_WRITE_MT.
665 * Luckily the KD variants differ only by one bit (0x08) from the
666 * normal variant. So don't wonder about code like:
667 * if (dasd_eckd_cdl_special(blk_per_trk, recid))
668 * ccw->cmd_code |= 0x8;
669 */
670static inline int
671dasd_eckd_cdl_special(int blk_per_trk, int recid)
672{
673 if (recid < 3)
674 return 1;
675 if (recid < blk_per_trk)
676 return 0;
677 if (recid < 2 * blk_per_trk)
678 return 1;
679 return 0;
680}
681
682/*
683 * Returns the record size for the special blocks of the cdl format.
684 * Only returns something useful if dasd_eckd_cdl_special is true
685 * for the recid.
686 */
687static inline int
688dasd_eckd_cdl_reclen(int recid)
689{
690 if (recid < 3)
691 return sizes_trk0[recid];
692 return LABEL_SIZE;
693}
694
3d052595
HH
695/*
696 * Generate device unique id that specifies the physical device.
697 */
4abb08c2
SW
698static int dasd_eckd_generate_uid(struct dasd_device *device,
699 struct dasd_uid *uid)
3d052595
HH
700{
701 struct dasd_eckd_private *private;
4abb08c2 702 int count;
3d052595
HH
703
704 private = (struct dasd_eckd_private *) device->private;
705 if (!private)
706 return -ENODEV;
4abb08c2 707 if (!private->ned || !private->gneq)
3d052595
HH
708 return -ENODEV;
709
710 memset(uid, 0, sizeof(struct dasd_uid));
4abb08c2 711 memcpy(uid->vendor, private->ned->HDA_manufacturer,
d0710c7c 712 sizeof(uid->vendor) - 1);
3d052595 713 EBCASC(uid->vendor, sizeof(uid->vendor) - 1);
4abb08c2 714 memcpy(uid->serial, private->ned->HDA_location,
d0710c7c 715 sizeof(uid->serial) - 1);
3d052595 716 EBCASC(uid->serial, sizeof(uid->serial) - 1);
4abb08c2
SW
717 uid->ssid = private->gneq->subsystemID;
718 uid->real_unit_addr = private->ned->unit_addr;;
719 if (private->sneq) {
720 uid->type = private->sneq->sua_flags;
8e09f215 721 if (uid->type == UA_BASE_PAV_ALIAS)
4abb08c2 722 uid->base_unit_addr = private->sneq->base_unit_addr;
8e09f215
SW
723 } else {
724 uid->type = UA_BASE_DEVICE;
725 }
4abb08c2
SW
726 if (private->vdsneq) {
727 for (count = 0; count < 16; count++) {
728 sprintf(uid->vduit+2*count, "%02x",
729 private->vdsneq->uit[count]);
730 }
731 }
3d052595
HH
732 return 0;
733}
734
763968e2
HC
735static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
736 void *rcd_buffer,
737 struct ciw *ciw, __u8 lpm)
17283b56
CH
738{
739 struct dasd_ccw_req *cqr;
740 struct ccw1 *ccw;
741
742 cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
743
744 if (IS_ERR(cqr)) {
745 DEV_MESSAGE(KERN_WARNING, device, "%s",
746 "Could not allocate RCD request");
747 return cqr;
748 }
749
750 ccw = cqr->cpaddr;
751 ccw->cmd_code = ciw->cmd;
752 ccw->cda = (__u32)(addr_t)rcd_buffer;
753 ccw->count = ciw->count;
754
8e09f215
SW
755 cqr->startdev = device;
756 cqr->memdev = device;
757 cqr->block = NULL;
17283b56
CH
758 cqr->expires = 10*HZ;
759 cqr->lpm = lpm;
760 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
761 cqr->retries = 2;
762 cqr->buildclk = get_clock();
763 cqr->status = DASD_CQR_FILLED;
764 return cqr;
765}
766
767static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
768 void **rcd_buffer,
769 int *rcd_buffer_size, __u8 lpm)
770{
771 struct ciw *ciw;
772 char *rcd_buf = NULL;
773 int ret;
774 struct dasd_ccw_req *cqr;
775
776 /*
777 * scan for RCD command in extended SenseID data
778 */
779 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
780 if (!ciw || ciw->cmd == 0) {
781 ret = -EOPNOTSUPP;
782 goto out_error;
783 }
784 rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
785 if (!rcd_buf) {
786 ret = -ENOMEM;
787 goto out_error;
788 }
4abb08c2
SW
789
790 /*
791 * buffer has to start with EBCDIC "V1.0" to show
792 * support for virtual device SNEQ
793 */
794 rcd_buf[0] = 0xE5;
795 rcd_buf[1] = 0xF1;
796 rcd_buf[2] = 0x4B;
797 rcd_buf[3] = 0xF0;
17283b56
CH
798 cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm);
799 if (IS_ERR(cqr)) {
800 ret = PTR_ERR(cqr);
801 goto out_error;
802 }
803 ret = dasd_sleep_on(cqr);
804 /*
805 * on success we update the user input parms
806 */
8e09f215 807 dasd_sfree_request(cqr, cqr->memdev);
17283b56
CH
808 if (ret)
809 goto out_error;
810
811 *rcd_buffer_size = ciw->count;
812 *rcd_buffer = rcd_buf;
813 return 0;
814out_error:
815 kfree(rcd_buf);
816 *rcd_buffer = NULL;
817 *rcd_buffer_size = 0;
818 return ret;
819}
820
4abb08c2
SW
821static int dasd_eckd_identify_conf_parts(struct dasd_eckd_private *private)
822{
823
824 struct dasd_sneq *sneq;
825 int i, count;
826
827 private->ned = NULL;
828 private->sneq = NULL;
829 private->vdsneq = NULL;
830 private->gneq = NULL;
831 count = private->conf_len / sizeof(struct dasd_sneq);
832 sneq = (struct dasd_sneq *)private->conf_data;
833 for (i = 0; i < count; ++i) {
834 if (sneq->flags.identifier == 1 && sneq->format == 1)
835 private->sneq = sneq;
836 else if (sneq->flags.identifier == 1 && sneq->format == 4)
837 private->vdsneq = (struct vd_sneq *)sneq;
838 else if (sneq->flags.identifier == 2)
839 private->gneq = (struct dasd_gneq *)sneq;
840 else if (sneq->flags.identifier == 3 && sneq->res1 == 1)
841 private->ned = (struct dasd_ned *)sneq;
842 sneq++;
843 }
844 if (!private->ned || !private->gneq) {
845 private->ned = NULL;
846 private->sneq = NULL;
847 private->vdsneq = NULL;
848 private->gneq = NULL;
849 return -EINVAL;
850 }
851 return 0;
852
853};
854
855static unsigned char dasd_eckd_path_access(void *conf_data, int conf_len)
856{
857 struct dasd_gneq *gneq;
858 int i, count, found;
859
860 count = conf_len / sizeof(*gneq);
861 gneq = (struct dasd_gneq *)conf_data;
862 found = 0;
863 for (i = 0; i < count; ++i) {
864 if (gneq->flags.identifier == 2) {
865 found = 1;
866 break;
867 }
868 gneq++;
869 }
870 if (found)
871 return ((char *)gneq)[18] & 0x07;
872 else
873 return 0;
874}
875
876static int dasd_eckd_read_conf(struct dasd_device *device)
1da177e4
LT
877{
878 void *conf_data;
879 int conf_len, conf_data_saved;
880 int rc;
881 __u8 lpm;
882 struct dasd_eckd_private *private;
883 struct dasd_eckd_path *path_data;
884
885 private = (struct dasd_eckd_private *) device->private;
886 path_data = (struct dasd_eckd_path *) &private->path_data;
887 path_data->opm = ccw_device_get_path_mask(device->cdev);
888 lpm = 0x80;
889 conf_data_saved = 0;
1da177e4
LT
890 /* get configuration data per operational path */
891 for (lpm = 0x80; lpm; lpm>>= 1) {
892 if (lpm & path_data->opm){
17283b56
CH
893 rc = dasd_eckd_read_conf_lpm(device, &conf_data,
894 &conf_len, lpm);
1da177e4
LT
895 if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
896 MESSAGE(KERN_WARNING,
897 "Read configuration data returned "
898 "error %d", rc);
899 return rc;
900 }
901 if (conf_data == NULL) {
902 MESSAGE(KERN_WARNING, "%s", "No configuration "
903 "data retrieved");
d133a960 904 continue; /* no error */
1da177e4 905 }
1da177e4 906 /* save first valid configuration data */
4abb08c2
SW
907 if (!conf_data_saved) {
908 kfree(private->conf_data);
909 private->conf_data = conf_data;
910 private->conf_len = conf_len;
911 if (dasd_eckd_identify_conf_parts(private)) {
912 private->conf_data = NULL;
913 private->conf_len = 0;
914 kfree(conf_data);
915 continue;
916 }
1da177e4
LT
917 conf_data_saved++;
918 }
4abb08c2 919 switch (dasd_eckd_path_access(conf_data, conf_len)) {
1da177e4
LT
920 case 0x02:
921 path_data->npm |= lpm;
922 break;
923 case 0x03:
924 path_data->ppm |= lpm;
925 break;
926 }
4abb08c2
SW
927 if (conf_data != private->conf_data)
928 kfree(conf_data);
1da177e4
LT
929 }
930 }
931 return 0;
932}
933
8e09f215
SW
934static int dasd_eckd_read_features(struct dasd_device *device)
935{
936 struct dasd_psf_prssd_data *prssdp;
937 struct dasd_rssd_features *features;
938 struct dasd_ccw_req *cqr;
939 struct ccw1 *ccw;
940 int rc;
941 struct dasd_eckd_private *private;
942
943 private = (struct dasd_eckd_private *) device->private;
944 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
945 1 /* PSF */ + 1 /* RSSD */ ,
946 (sizeof(struct dasd_psf_prssd_data) +
947 sizeof(struct dasd_rssd_features)),
948 device);
949 if (IS_ERR(cqr)) {
950 DEV_MESSAGE(KERN_WARNING, device, "%s",
951 "Could not allocate initialization request");
952 return PTR_ERR(cqr);
953 }
954 cqr->startdev = device;
955 cqr->memdev = device;
956 cqr->block = NULL;
957 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
958 cqr->retries = 5;
959 cqr->expires = 10 * HZ;
960
961 /* Prepare for Read Subsystem Data */
962 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
963 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
964 prssdp->order = PSF_ORDER_PRSSD;
965 prssdp->suborder = 0x41; /* Read Feature Codes */
966 /* all other bytes of prssdp must be zero */
967
968 ccw = cqr->cpaddr;
969 ccw->cmd_code = DASD_ECKD_CCW_PSF;
970 ccw->count = sizeof(struct dasd_psf_prssd_data);
971 ccw->flags |= CCW_FLAG_CC;
972 ccw->cda = (__u32)(addr_t) prssdp;
973
974 /* Read Subsystem Data - feature codes */
975 features = (struct dasd_rssd_features *) (prssdp + 1);
976 memset(features, 0, sizeof(struct dasd_rssd_features));
977
978 ccw++;
979 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
980 ccw->count = sizeof(struct dasd_rssd_features);
981 ccw->cda = (__u32)(addr_t) features;
982
983 cqr->buildclk = get_clock();
984 cqr->status = DASD_CQR_FILLED;
985 rc = dasd_sleep_on(cqr);
986 if (rc == 0) {
987 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
988 features = (struct dasd_rssd_features *) (prssdp + 1);
989 memcpy(&private->features, features,
990 sizeof(struct dasd_rssd_features));
991 }
992 dasd_sfree_request(cqr, cqr->memdev);
993 return rc;
994}
995
996
40545573
HH
997/*
998 * Build CP for Perform Subsystem Function - SSC.
999 */
f3eb5384
SW
1000static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
1001 int enable_pav)
40545573 1002{
8e09f215
SW
1003 struct dasd_ccw_req *cqr;
1004 struct dasd_psf_ssc_data *psf_ssc_data;
1005 struct ccw1 *ccw;
40545573 1006
8e09f215 1007 cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ ,
40545573
HH
1008 sizeof(struct dasd_psf_ssc_data),
1009 device);
1010
8e09f215
SW
1011 if (IS_ERR(cqr)) {
1012 DEV_MESSAGE(KERN_WARNING, device, "%s",
40545573 1013 "Could not allocate PSF-SSC request");
8e09f215
SW
1014 return cqr;
1015 }
1016 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
1017 psf_ssc_data->order = PSF_ORDER_SSC;
f3eb5384
SW
1018 psf_ssc_data->suborder = 0x40;
1019 if (enable_pav) {
1020 psf_ssc_data->suborder |= 0x88;
1021 psf_ssc_data->reserved[0] = 0x88;
1022 }
8e09f215
SW
1023 ccw = cqr->cpaddr;
1024 ccw->cmd_code = DASD_ECKD_CCW_PSF;
1025 ccw->cda = (__u32)(addr_t)psf_ssc_data;
1026 ccw->count = 66;
1027
1028 cqr->startdev = device;
1029 cqr->memdev = device;
1030 cqr->block = NULL;
1031 cqr->expires = 10*HZ;
1032 cqr->buildclk = get_clock();
1033 cqr->status = DASD_CQR_FILLED;
1034 return cqr;
40545573
HH
1035}
1036
1037/*
1038 * Perform Subsystem Function.
1039 * It is necessary to trigger CIO for channel revalidation since this
1040 * call might change behaviour of DASD devices.
1041 */
1042static int
f3eb5384 1043dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
40545573 1044{
8e09f215
SW
1045 struct dasd_ccw_req *cqr;
1046 int rc;
1047
f3eb5384 1048 cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
8e09f215
SW
1049 if (IS_ERR(cqr))
1050 return PTR_ERR(cqr);
1051
1052 rc = dasd_sleep_on(cqr);
1053 if (!rc)
1054 /* trigger CIO to reprobe devices */
1055 css_schedule_reprobe();
1056 dasd_sfree_request(cqr, cqr->memdev);
1057 return rc;
40545573
HH
1058}
1059
1060/*
1061 * Valide storage server of current device.
1062 */
8e09f215 1063static int dasd_eckd_validate_server(struct dasd_device *device)
40545573
HH
1064{
1065 int rc;
8e09f215 1066 struct dasd_eckd_private *private;
f3eb5384 1067 int enable_pav;
40545573 1068
40545573 1069 if (dasd_nopav || MACHINE_IS_VM)
f3eb5384
SW
1070 enable_pav = 0;
1071 else
1072 enable_pav = 1;
1073 rc = dasd_eckd_psf_ssc(device, enable_pav);
8e79a441
HH
1074 /* may be requested feature is not available on server,
1075 * therefore just report error and go ahead */
8e09f215 1076 private = (struct dasd_eckd_private *) device->private;
8e79a441
HH
1077 DEV_MESSAGE(KERN_INFO, device,
1078 "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d",
8e09f215
SW
1079 private->uid.vendor, private->uid.serial,
1080 private->uid.ssid, rc);
40545573
HH
1081 /* RE-Read Configuration Data */
1082 return dasd_eckd_read_conf(device);
1083}
1084
3d052595
HH
1085/*
1086 * Check device characteristics.
1087 * If the device is accessible using ECKD discipline, the device is enabled.
1088 */
1da177e4
LT
1089static int
1090dasd_eckd_check_characteristics(struct dasd_device *device)
1091{
1092 struct dasd_eckd_private *private;
8e09f215 1093 struct dasd_block *block;
1da177e4 1094 void *rdc_data;
8e09f215 1095 int is_known, rc;
1da177e4
LT
1096
1097 private = (struct dasd_eckd_private *) device->private;
1098 if (private == NULL) {
138c014d 1099 private = kzalloc(sizeof(struct dasd_eckd_private),
1da177e4
LT
1100 GFP_KERNEL | GFP_DMA);
1101 if (private == NULL) {
1102 DEV_MESSAGE(KERN_WARNING, device, "%s",
1103 "memory allocation failed for private "
1104 "data");
1105 return -ENOMEM;
1106 }
1da177e4
LT
1107 device->private = (void *) private;
1108 }
1109 /* Invalidate status of initial analysis. */
1110 private->init_cqr_status = -1;
1111 /* Set default cache operations. */
1112 private->attrib.operation = DASD_NORMAL_CACHE;
1113 private->attrib.nr_cyl = 0;
1114
40545573
HH
1115 /* Read Configuration Data */
1116 rc = dasd_eckd_read_conf(device);
1117 if (rc)
8e09f215 1118 goto out_err1;
40545573
HH
1119
1120 /* Generate device unique id and register in devmap */
8e09f215 1121 rc = dasd_eckd_generate_uid(device, &private->uid);
40545573 1122 if (rc)
8e09f215
SW
1123 goto out_err1;
1124 dasd_set_uid(device->cdev, &private->uid);
1125
1126 if (private->uid.type == UA_BASE_DEVICE) {
1127 block = dasd_alloc_block();
1128 if (IS_ERR(block)) {
1129 DEV_MESSAGE(KERN_WARNING, device, "%s",
1130 "could not allocate dasd block structure");
1131 rc = PTR_ERR(block);
1132 goto out_err1;
1133 }
1134 device->block = block;
1135 block->base = device;
1136 }
1137
1138 /* register lcu with alias handling, enable PAV if this is a new lcu */
1139 is_known = dasd_alias_make_device_known_to_lcu(device);
1140 if (is_known < 0) {
1141 rc = is_known;
1142 goto out_err2;
1143 }
1144 if (!is_known) {
1145 /* new lcu found */
1146 rc = dasd_eckd_validate_server(device); /* will switch pav on */
1147 if (rc)
1148 goto out_err3;
1149 }
1150
1151 /* Read Feature Codes */
1152 rc = dasd_eckd_read_features(device);
40545573 1153 if (rc)
8e09f215 1154 goto out_err3;
40545573 1155
1da177e4
LT
1156 /* Read Device Characteristics */
1157 rdc_data = (void *) &(private->rdc_data);
3d052595 1158 memset(rdc_data, 0, sizeof(rdc_data));
17283b56 1159 rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
8e09f215 1160 if (rc) {
1da177e4 1161 DEV_MESSAGE(KERN_WARNING, device,
40545573
HH
1162 "Read device characteristics returned "
1163 "rc=%d", rc);
8e09f215
SW
1164 goto out_err3;
1165 }
b44b0ab3
SW
1166 /* find the vaild cylinder size */
1167 if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
1168 private->rdc_data.long_no_cyl)
1169 private->real_cyl = private->rdc_data.long_no_cyl;
1170 else
1171 private->real_cyl = private->rdc_data.no_cyl;
1172
1da177e4
LT
1173 DEV_MESSAGE(KERN_INFO, device,
1174 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
1175 private->rdc_data.dev_type,
1176 private->rdc_data.dev_model,
1177 private->rdc_data.cu_type,
1178 private->rdc_data.cu_model.model,
b44b0ab3 1179 private->real_cyl,
1da177e4
LT
1180 private->rdc_data.trk_per_cyl,
1181 private->rdc_data.sec_per_trk);
8e09f215
SW
1182 return 0;
1183
1184out_err3:
1185 dasd_alias_disconnect_device_from_lcu(device);
1186out_err2:
1187 dasd_free_block(device->block);
1188 device->block = NULL;
1189out_err1:
4abb08c2 1190 kfree(private->conf_data);
8e09f215
SW
1191 kfree(device->private);
1192 device->private = NULL;
3d052595 1193 return rc;
1da177e4
LT
1194}
1195
8e09f215
SW
1196static void dasd_eckd_uncheck_device(struct dasd_device *device)
1197{
4abb08c2
SW
1198 struct dasd_eckd_private *private;
1199
1200 private = (struct dasd_eckd_private *) device->private;
8e09f215 1201 dasd_alias_disconnect_device_from_lcu(device);
4abb08c2
SW
1202 private->ned = NULL;
1203 private->sneq = NULL;
1204 private->vdsneq = NULL;
1205 private->gneq = NULL;
1206 private->conf_len = 0;
1207 kfree(private->conf_data);
1208 private->conf_data = NULL;
8e09f215
SW
1209}
1210
1da177e4
LT
1211static struct dasd_ccw_req *
1212dasd_eckd_analysis_ccw(struct dasd_device *device)
1213{
1214 struct dasd_eckd_private *private;
1215 struct eckd_count *count_data;
1216 struct LO_eckd_data *LO_data;
1217 struct dasd_ccw_req *cqr;
1218 struct ccw1 *ccw;
1219 int cplength, datasize;
1220 int i;
1221
1222 private = (struct dasd_eckd_private *) device->private;
1223
1224 cplength = 8;
1225 datasize = sizeof(struct DE_eckd_data) + 2*sizeof(struct LO_eckd_data);
1226 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1227 cplength, datasize, device);
1228 if (IS_ERR(cqr))
1229 return cqr;
1230 ccw = cqr->cpaddr;
1231 /* Define extent for the first 3 tracks. */
1232 define_extent(ccw++, cqr->data, 0, 2,
1233 DASD_ECKD_CCW_READ_COUNT, device);
8e09f215 1234 LO_data = cqr->data + sizeof(struct DE_eckd_data);
1da177e4
LT
1235 /* Locate record for the first 4 records on track 0. */
1236 ccw[-1].flags |= CCW_FLAG_CC;
1237 locate_record(ccw++, LO_data++, 0, 0, 4,
1238 DASD_ECKD_CCW_READ_COUNT, device, 0);
1239
1240 count_data = private->count_area;
1241 for (i = 0; i < 4; i++) {
1242 ccw[-1].flags |= CCW_FLAG_CC;
1243 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
1244 ccw->flags = 0;
1245 ccw->count = 8;
1246 ccw->cda = (__u32)(addr_t) count_data;
1247 ccw++;
1248 count_data++;
1249 }
1250
1251 /* Locate record for the first record on track 2. */
1252 ccw[-1].flags |= CCW_FLAG_CC;
1253 locate_record(ccw++, LO_data++, 2, 0, 1,
1254 DASD_ECKD_CCW_READ_COUNT, device, 0);
1255 /* Read count ccw. */
1256 ccw[-1].flags |= CCW_FLAG_CC;
1257 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
1258 ccw->flags = 0;
1259 ccw->count = 8;
1260 ccw->cda = (__u32)(addr_t) count_data;
1261
8e09f215
SW
1262 cqr->block = NULL;
1263 cqr->startdev = device;
1264 cqr->memdev = device;
1da177e4
LT
1265 cqr->retries = 0;
1266 cqr->buildclk = get_clock();
1267 cqr->status = DASD_CQR_FILLED;
1268 return cqr;
1269}
1270
1271/*
1272 * This is the callback function for the init_analysis cqr. It saves
1273 * the status of the initial analysis ccw before it frees it and kicks
1274 * the device to continue the startup sequence. This will call
1275 * dasd_eckd_do_analysis again (if the devices has not been marked
1276 * for deletion in the meantime).
1277 */
1278static void
1279dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data)
1280{
1281 struct dasd_eckd_private *private;
1282 struct dasd_device *device;
1283
8e09f215 1284 device = init_cqr->startdev;
1da177e4
LT
1285 private = (struct dasd_eckd_private *) device->private;
1286 private->init_cqr_status = init_cqr->status;
1287 dasd_sfree_request(init_cqr, device);
1288 dasd_kick_device(device);
1289}
1290
1291static int
8e09f215 1292dasd_eckd_start_analysis(struct dasd_block *block)
1da177e4
LT
1293{
1294 struct dasd_eckd_private *private;
1295 struct dasd_ccw_req *init_cqr;
1296
8e09f215
SW
1297 private = (struct dasd_eckd_private *) block->base->private;
1298 init_cqr = dasd_eckd_analysis_ccw(block->base);
1da177e4
LT
1299 if (IS_ERR(init_cqr))
1300 return PTR_ERR(init_cqr);
1301 init_cqr->callback = dasd_eckd_analysis_callback;
1302 init_cqr->callback_data = NULL;
1303 init_cqr->expires = 5*HZ;
1304 dasd_add_request_head(init_cqr);
1305 return -EAGAIN;
1306}
1307
1308static int
8e09f215 1309dasd_eckd_end_analysis(struct dasd_block *block)
1da177e4 1310{
8e09f215 1311 struct dasd_device *device;
1da177e4
LT
1312 struct dasd_eckd_private *private;
1313 struct eckd_count *count_area;
1314 unsigned int sb, blk_per_trk;
1315 int status, i;
1316
8e09f215 1317 device = block->base;
1da177e4
LT
1318 private = (struct dasd_eckd_private *) device->private;
1319 status = private->init_cqr_status;
1320 private->init_cqr_status = -1;
1321 if (status != DASD_CQR_DONE) {
1322 DEV_MESSAGE(KERN_WARNING, device, "%s",
1323 "volume analysis returned unformatted disk");
1324 return -EMEDIUMTYPE;
1325 }
1326
1327 private->uses_cdl = 1;
1da177e4
LT
1328 /* Check Track 0 for Compatible Disk Layout */
1329 count_area = NULL;
1330 for (i = 0; i < 3; i++) {
1331 if (private->count_area[i].kl != 4 ||
1332 private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4) {
1333 private->uses_cdl = 0;
1334 break;
1335 }
1336 }
1337 if (i == 3)
1338 count_area = &private->count_area[4];
1339
1340 if (private->uses_cdl == 0) {
1341 for (i = 0; i < 5; i++) {
1342 if ((private->count_area[i].kl != 0) ||
1343 (private->count_area[i].dl !=
1344 private->count_area[0].dl))
1345 break;
1346 }
1347 if (i == 5)
1348 count_area = &private->count_area[0];
1349 } else {
1350 if (private->count_area[3].record == 1)
1351 DEV_MESSAGE(KERN_WARNING, device, "%s",
1352 "Trk 0: no records after VTOC!");
1353 }
1354 if (count_area != NULL && count_area->kl == 0) {
1355 /* we found notthing violating our disk layout */
1356 if (dasd_check_blocksize(count_area->dl) == 0)
8e09f215 1357 block->bp_block = count_area->dl;
1da177e4 1358 }
8e09f215 1359 if (block->bp_block == 0) {
1da177e4
LT
1360 DEV_MESSAGE(KERN_WARNING, device, "%s",
1361 "Volume has incompatible disk layout");
1362 return -EMEDIUMTYPE;
1363 }
8e09f215
SW
1364 block->s2b_shift = 0; /* bits to shift 512 to get a block */
1365 for (sb = 512; sb < block->bp_block; sb = sb << 1)
1366 block->s2b_shift++;
1da177e4 1367
8e09f215 1368 blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
b44b0ab3 1369 block->blocks = (private->real_cyl *
1da177e4
LT
1370 private->rdc_data.trk_per_cyl *
1371 blk_per_trk);
1372
1373 DEV_MESSAGE(KERN_INFO, device,
1374 "(%dkB blks): %dkB at %dkB/trk %s",
8e09f215 1375 (block->bp_block >> 10),
b44b0ab3 1376 ((private->real_cyl *
1da177e4 1377 private->rdc_data.trk_per_cyl *
8e09f215
SW
1378 blk_per_trk * (block->bp_block >> 9)) >> 1),
1379 ((blk_per_trk * block->bp_block) >> 10),
1da177e4
LT
1380 private->uses_cdl ?
1381 "compatible disk layout" : "linux disk layout");
1382
1383 return 0;
1384}
1385
8e09f215 1386static int dasd_eckd_do_analysis(struct dasd_block *block)
1da177e4
LT
1387{
1388 struct dasd_eckd_private *private;
1389
8e09f215 1390 private = (struct dasd_eckd_private *) block->base->private;
1da177e4 1391 if (private->init_cqr_status < 0)
8e09f215 1392 return dasd_eckd_start_analysis(block);
1da177e4 1393 else
8e09f215 1394 return dasd_eckd_end_analysis(block);
1da177e4
LT
1395}
1396
8e09f215
SW
1397static int dasd_eckd_ready_to_online(struct dasd_device *device)
1398{
1399 return dasd_alias_add_device(device);
1400};
1401
1402static int dasd_eckd_online_to_ready(struct dasd_device *device)
1403{
1404 return dasd_alias_remove_device(device);
1405};
1406
1da177e4 1407static int
8e09f215 1408dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo)
1da177e4
LT
1409{
1410 struct dasd_eckd_private *private;
1411
8e09f215
SW
1412 private = (struct dasd_eckd_private *) block->base->private;
1413 if (dasd_check_blocksize(block->bp_block) == 0) {
1da177e4 1414 geo->sectors = recs_per_track(&private->rdc_data,
8e09f215 1415 0, block->bp_block);
1da177e4
LT
1416 }
1417 geo->cylinders = private->rdc_data.no_cyl;
1418 geo->heads = private->rdc_data.trk_per_cyl;
1419 return 0;
1420}
1421
1422static struct dasd_ccw_req *
1423dasd_eckd_format_device(struct dasd_device * device,
1424 struct format_data_t * fdata)
1425{
1426 struct dasd_eckd_private *private;
1427 struct dasd_ccw_req *fcp;
1428 struct eckd_count *ect;
1429 struct ccw1 *ccw;
1430 void *data;
b44b0ab3
SW
1431 int rpt;
1432 struct ch_t address;
1da177e4
LT
1433 int cplength, datasize;
1434 int i;
f9a28f7b
JBJ
1435 int intensity = 0;
1436 int r0_perm;
1da177e4
LT
1437
1438 private = (struct dasd_eckd_private *) device->private;
1439 rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
b44b0ab3
SW
1440 set_ch_t(&address,
1441 fdata->start_unit / private->rdc_data.trk_per_cyl,
1442 fdata->start_unit % private->rdc_data.trk_per_cyl);
1da177e4
LT
1443
1444 /* Sanity checks. */
1445 if (fdata->start_unit >=
b44b0ab3
SW
1446 (private->real_cyl * private->rdc_data.trk_per_cyl)) {
1447 DEV_MESSAGE(KERN_INFO, device, "Track no %u too big!",
1da177e4
LT
1448 fdata->start_unit);
1449 return ERR_PTR(-EINVAL);
1450 }
1451 if (fdata->start_unit > fdata->stop_unit) {
b44b0ab3 1452 DEV_MESSAGE(KERN_INFO, device, "Track %u reached! ending.",
1da177e4
LT
1453 fdata->start_unit);
1454 return ERR_PTR(-EINVAL);
1455 }
1456 if (dasd_check_blocksize(fdata->blksize) != 0) {
1457 DEV_MESSAGE(KERN_WARNING, device,
b44b0ab3 1458 "Invalid blocksize %u...terminating!",
1da177e4
LT
1459 fdata->blksize);
1460 return ERR_PTR(-EINVAL);
1461 }
1462
1463 /*
1464 * fdata->intensity is a bit string that tells us what to do:
1465 * Bit 0: write record zero
1466 * Bit 1: write home address, currently not supported
1467 * Bit 2: invalidate tracks
1468 * Bit 3: use OS/390 compatible disk layout (cdl)
f9a28f7b 1469 * Bit 4: do not allow storage subsystem to modify record zero
1da177e4
LT
1470 * Only some bit combinations do make sense.
1471 */
f9a28f7b
JBJ
1472 if (fdata->intensity & 0x10) {
1473 r0_perm = 0;
1474 intensity = fdata->intensity & ~0x10;
1475 } else {
1476 r0_perm = 1;
1477 intensity = fdata->intensity;
1478 }
1479 switch (intensity) {
1da177e4
LT
1480 case 0x00: /* Normal format */
1481 case 0x08: /* Normal format, use cdl. */
1482 cplength = 2 + rpt;
1483 datasize = sizeof(struct DE_eckd_data) +
1484 sizeof(struct LO_eckd_data) +
1485 rpt * sizeof(struct eckd_count);
1486 break;
1487 case 0x01: /* Write record zero and format track. */
1488 case 0x09: /* Write record zero and format track, use cdl. */
1489 cplength = 3 + rpt;
1490 datasize = sizeof(struct DE_eckd_data) +
1491 sizeof(struct LO_eckd_data) +
1492 sizeof(struct eckd_count) +
1493 rpt * sizeof(struct eckd_count);
1494 break;
1495 case 0x04: /* Invalidate track. */
1496 case 0x0c: /* Invalidate track, use cdl. */
1497 cplength = 3;
1498 datasize = sizeof(struct DE_eckd_data) +
1499 sizeof(struct LO_eckd_data) +
1500 sizeof(struct eckd_count);
1501 break;
1502 default:
1503 DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
1504 fdata->intensity);
1505 return ERR_PTR(-EINVAL);
1506 }
1507 /* Allocate the format ccw request. */
1508 fcp = dasd_smalloc_request(dasd_eckd_discipline.name,
1509 cplength, datasize, device);
1510 if (IS_ERR(fcp))
1511 return fcp;
1512
1513 data = fcp->data;
1514 ccw = fcp->cpaddr;
1515
f9a28f7b 1516 switch (intensity & ~0x08) {
1da177e4
LT
1517 case 0x00: /* Normal format. */
1518 define_extent(ccw++, (struct DE_eckd_data *) data,
1519 fdata->start_unit, fdata->start_unit,
1520 DASD_ECKD_CCW_WRITE_CKD, device);
f9a28f7b
JBJ
1521 /* grant subsystem permission to format R0 */
1522 if (r0_perm)
1523 ((struct DE_eckd_data *)data)->ga_extended |= 0x04;
1da177e4
LT
1524 data += sizeof(struct DE_eckd_data);
1525 ccw[-1].flags |= CCW_FLAG_CC;
1526 locate_record(ccw++, (struct LO_eckd_data *) data,
1527 fdata->start_unit, 0, rpt,
1528 DASD_ECKD_CCW_WRITE_CKD, device,
1529 fdata->blksize);
1530 data += sizeof(struct LO_eckd_data);
1531 break;
1532 case 0x01: /* Write record zero + format track. */
1533 define_extent(ccw++, (struct DE_eckd_data *) data,
1534 fdata->start_unit, fdata->start_unit,
1535 DASD_ECKD_CCW_WRITE_RECORD_ZERO,
1536 device);
1537 data += sizeof(struct DE_eckd_data);
1538 ccw[-1].flags |= CCW_FLAG_CC;
1539 locate_record(ccw++, (struct LO_eckd_data *) data,
1540 fdata->start_unit, 0, rpt + 1,
1541 DASD_ECKD_CCW_WRITE_RECORD_ZERO, device,
8e09f215 1542 device->block->bp_block);
1da177e4
LT
1543 data += sizeof(struct LO_eckd_data);
1544 break;
1545 case 0x04: /* Invalidate track. */
1546 define_extent(ccw++, (struct DE_eckd_data *) data,
1547 fdata->start_unit, fdata->start_unit,
1548 DASD_ECKD_CCW_WRITE_CKD, device);
1549 data += sizeof(struct DE_eckd_data);
1550 ccw[-1].flags |= CCW_FLAG_CC;
1551 locate_record(ccw++, (struct LO_eckd_data *) data,
1552 fdata->start_unit, 0, 1,
1553 DASD_ECKD_CCW_WRITE_CKD, device, 8);
1554 data += sizeof(struct LO_eckd_data);
1555 break;
1556 }
f9a28f7b 1557 if (intensity & 0x01) { /* write record zero */
1da177e4
LT
1558 ect = (struct eckd_count *) data;
1559 data += sizeof(struct eckd_count);
b44b0ab3
SW
1560 ect->cyl = address.cyl;
1561 ect->head = address.head;
1da177e4
LT
1562 ect->record = 0;
1563 ect->kl = 0;
1564 ect->dl = 8;
1565 ccw[-1].flags |= CCW_FLAG_CC;
1566 ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO;
1567 ccw->flags = CCW_FLAG_SLI;
1568 ccw->count = 8;
1569 ccw->cda = (__u32)(addr_t) ect;
1570 ccw++;
1571 }
f9a28f7b 1572 if ((intensity & ~0x08) & 0x04) { /* erase track */
1da177e4
LT
1573 ect = (struct eckd_count *) data;
1574 data += sizeof(struct eckd_count);
b44b0ab3
SW
1575 ect->cyl = address.cyl;
1576 ect->head = address.head;
1da177e4
LT
1577 ect->record = 1;
1578 ect->kl = 0;
1579 ect->dl = 0;
1580 ccw[-1].flags |= CCW_FLAG_CC;
1581 ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;
1582 ccw->flags = CCW_FLAG_SLI;
1583 ccw->count = 8;
1584 ccw->cda = (__u32)(addr_t) ect;
1585 } else { /* write remaining records */
1586 for (i = 0; i < rpt; i++) {
1587 ect = (struct eckd_count *) data;
1588 data += sizeof(struct eckd_count);
b44b0ab3
SW
1589 ect->cyl = address.cyl;
1590 ect->head = address.head;
1da177e4
LT
1591 ect->record = i + 1;
1592 ect->kl = 0;
1593 ect->dl = fdata->blksize;
1594 /* Check for special tracks 0-1 when formatting CDL */
f9a28f7b 1595 if ((intensity & 0x08) &&
1da177e4
LT
1596 fdata->start_unit == 0) {
1597 if (i < 3) {
1598 ect->kl = 4;
1599 ect->dl = sizes_trk0[i] - 4;
138c014d 1600 }
1da177e4 1601 }
f9a28f7b 1602 if ((intensity & 0x08) &&
1da177e4
LT
1603 fdata->start_unit == 1) {
1604 ect->kl = 44;
1605 ect->dl = LABEL_SIZE - 44;
1606 }
1607 ccw[-1].flags |= CCW_FLAG_CC;
1608 ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;
1609 ccw->flags = CCW_FLAG_SLI;
1610 ccw->count = 8;
1611 ccw->cda = (__u32)(addr_t) ect;
1612 ccw++;
1613 }
1614 }
8e09f215
SW
1615 fcp->startdev = device;
1616 fcp->memdev = device;
1617 clear_bit(DASD_CQR_FLAGS_USE_ERP, &fcp->flags);
1618 fcp->retries = 5; /* set retry counter to enable default ERP */
1da177e4
LT
1619 fcp->buildclk = get_clock();
1620 fcp->status = DASD_CQR_FILLED;
1621 return fcp;
1622}
1623
8e09f215 1624static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)
1da177e4 1625{
8e09f215
SW
1626 cqr->status = DASD_CQR_FILLED;
1627 if (cqr->block && (cqr->startdev != cqr->block->base)) {
1628 dasd_eckd_reset_ccw_to_base_io(cqr);
1629 cqr->startdev = cqr->block->base;
1da177e4 1630 }
8e09f215 1631};
1da177e4
LT
1632
1633static dasd_erp_fn_t
1634dasd_eckd_erp_action(struct dasd_ccw_req * cqr)
1635{
8e09f215 1636 struct dasd_device *device = (struct dasd_device *) cqr->startdev;
1da177e4
LT
1637 struct ccw_device *cdev = device->cdev;
1638
1639 switch (cdev->id.cu_type) {
1640 case 0x3990:
1641 case 0x2105:
1642 case 0x2107:
1643 case 0x1750:
1644 return dasd_3990_erp_action;
1645 case 0x9343:
1646 case 0x3880:
1647 default:
1648 return dasd_default_erp_action;
1649 }
1650}
1651
1652static dasd_erp_fn_t
1653dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr)
1654{
1655 return dasd_default_erp_postaction;
1656}
1657
8e09f215
SW
1658
1659static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
1660 struct irb *irb)
1661{
1662 char mask;
f3eb5384 1663 char *sense = NULL;
8e09f215
SW
1664
1665 /* first of all check for state change pending interrupt */
1666 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
f3eb5384 1667 if ((scsw_dstat(&irb->scsw) & mask) == mask) {
8e09f215
SW
1668 dasd_generic_handle_state_change(device);
1669 return;
1670 }
1671
1672 /* summary unit check */
f3eb5384 1673 if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
23d805b6 1674 (irb->ecw[7] == 0x0D)) {
8e09f215
SW
1675 dasd_alias_handle_summary_unit_check(device, irb);
1676 return;
1677 }
1678
f3eb5384 1679 sense = dasd_get_sense(irb);
f60c768c 1680 /* service information message SIM */
f3eb5384
SW
1681 if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
1682 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
1683 dasd_3990_erp_handle_sim(device, sense);
9d853caf 1684 dasd_schedule_device_bh(device);
f60c768c
SH
1685 return;
1686 }
1687
f3eb5384
SW
1688 if ((scsw_cc(&irb->scsw) == 1) &&
1689 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
1690 (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
1691 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
ada3df91
SH
1692 /* fake irb do nothing, they are handled elsewhere */
1693 dasd_schedule_device_bh(device);
1694 return;
1695 }
8e09f215 1696
f3eb5384 1697 if (!sense) {
ada3df91
SH
1698 /* just report other unsolicited interrupts */
1699 DEV_MESSAGE(KERN_ERR, device, "%s",
1700 "unsolicited interrupt received");
1701 } else {
1702 DEV_MESSAGE(KERN_ERR, device, "%s",
1703 "unsolicited interrupt received "
1704 "(sense available)");
1705 device->discipline->dump_sense(device, NULL, irb);
1706 }
1707
1708 dasd_schedule_device_bh(device);
8e09f215
SW
1709 return;
1710};
1711
f3eb5384
SW
1712
1713static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
1714 struct dasd_device *startdev,
8e09f215 1715 struct dasd_block *block,
f3eb5384
SW
1716 struct request *req,
1717 sector_t first_rec,
1718 sector_t last_rec,
1719 sector_t first_trk,
1720 sector_t last_trk,
1721 unsigned int first_offs,
1722 unsigned int last_offs,
1723 unsigned int blk_per_trk,
1724 unsigned int blksize)
1da177e4
LT
1725{
1726 struct dasd_eckd_private *private;
1727 unsigned long *idaws;
1728 struct LO_eckd_data *LO_data;
1729 struct dasd_ccw_req *cqr;
1730 struct ccw1 *ccw;
5705f702 1731 struct req_iterator iter;
1da177e4
LT
1732 struct bio_vec *bv;
1733 char *dst;
f3eb5384 1734 unsigned int off;
1da177e4 1735 int count, cidaw, cplength, datasize;
f3eb5384 1736 sector_t recid;
1da177e4 1737 unsigned char cmd, rcmd;
8e09f215
SW
1738 int use_prefix;
1739 struct dasd_device *basedev;
1da177e4 1740
8e09f215
SW
1741 basedev = block->base;
1742 private = (struct dasd_eckd_private *) basedev->private;
1da177e4
LT
1743 if (rq_data_dir(req) == READ)
1744 cmd = DASD_ECKD_CCW_READ_MT;
1745 else if (rq_data_dir(req) == WRITE)
1746 cmd = DASD_ECKD_CCW_WRITE_MT;
1747 else
1748 return ERR_PTR(-EINVAL);
f3eb5384 1749
1da177e4
LT
1750 /* Check struct bio and count the number of blocks for the request. */
1751 count = 0;
1752 cidaw = 0;
5705f702 1753 rq_for_each_segment(bv, req, iter) {
6c92e699
JA
1754 if (bv->bv_len & (blksize - 1))
1755 /* Eckd can only do full blocks. */
1756 return ERR_PTR(-EINVAL);
8e09f215 1757 count += bv->bv_len >> (block->s2b_shift + 9);
347a8dc3 1758#if defined(CONFIG_64BIT)
6c92e699 1759 if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
8e09f215 1760 cidaw += bv->bv_len >> (block->s2b_shift + 9);
1da177e4 1761#endif
1da177e4
LT
1762 }
1763 /* Paranoia. */
1764 if (count != last_rec - first_rec + 1)
1765 return ERR_PTR(-EINVAL);
8e09f215
SW
1766
1767 /* use the prefix command if available */
1768 use_prefix = private->features.feature[8] & 0x01;
1769 if (use_prefix) {
1770 /* 1x prefix + number of blocks */
1771 cplength = 2 + count;
1772 /* 1x prefix + cidaws*sizeof(long) */
1773 datasize = sizeof(struct PFX_eckd_data) +
1774 sizeof(struct LO_eckd_data) +
1775 cidaw * sizeof(unsigned long);
1776 } else {
1777 /* 1x define extent + 1x locate record + number of blocks */
1778 cplength = 2 + count;
1779 /* 1x define extent + 1x locate record + cidaws*sizeof(long) */
1780 datasize = sizeof(struct DE_eckd_data) +
1781 sizeof(struct LO_eckd_data) +
1782 cidaw * sizeof(unsigned long);
1783 }
1da177e4
LT
1784 /* Find out the number of additional locate record ccws for cdl. */
1785 if (private->uses_cdl && first_rec < 2*blk_per_trk) {
1786 if (last_rec >= 2*blk_per_trk)
1787 count = 2*blk_per_trk - first_rec;
1788 cplength += count;
1789 datasize += count*sizeof(struct LO_eckd_data);
1790 }
1791 /* Allocate the ccw request. */
1792 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
8e09f215 1793 cplength, datasize, startdev);
1da177e4
LT
1794 if (IS_ERR(cqr))
1795 return cqr;
1796 ccw = cqr->cpaddr;
8e09f215
SW
1797 /* First ccw is define extent or prefix. */
1798 if (use_prefix) {
1799 if (prefix(ccw++, cqr->data, first_trk,
1800 last_trk, cmd, basedev, startdev) == -EAGAIN) {
1801 /* Clock not in sync and XRC is enabled.
1802 * Try again later.
1803 */
1804 dasd_sfree_request(cqr, startdev);
1805 return ERR_PTR(-EAGAIN);
1806 }
1807 idaws = (unsigned long *) (cqr->data +
1808 sizeof(struct PFX_eckd_data));
1809 } else {
1810 if (define_extent(ccw++, cqr->data, first_trk,
1811 last_trk, cmd, startdev) == -EAGAIN) {
1812 /* Clock not in sync and XRC is enabled.
1813 * Try again later.
1814 */
1815 dasd_sfree_request(cqr, startdev);
1816 return ERR_PTR(-EAGAIN);
1817 }
1818 idaws = (unsigned long *) (cqr->data +
1819 sizeof(struct DE_eckd_data));
d54853ef 1820 }
1da177e4 1821 /* Build locate_record+read/write/ccws. */
1da177e4
LT
1822 LO_data = (struct LO_eckd_data *) (idaws + cidaw);
1823 recid = first_rec;
1824 if (private->uses_cdl == 0 || recid > 2*blk_per_trk) {
1825 /* Only standard blocks so there is just one locate record. */
1826 ccw[-1].flags |= CCW_FLAG_CC;
1827 locate_record(ccw++, LO_data++, first_trk, first_offs + 1,
8e09f215 1828 last_rec - recid + 1, cmd, basedev, blksize);
1da177e4 1829 }
5705f702 1830 rq_for_each_segment(bv, req, iter) {
1da177e4
LT
1831 dst = page_address(bv->bv_page) + bv->bv_offset;
1832 if (dasd_page_cache) {
1833 char *copy = kmem_cache_alloc(dasd_page_cache,
441e143e 1834 GFP_DMA | __GFP_NOWARN);
1da177e4
LT
1835 if (copy && rq_data_dir(req) == WRITE)
1836 memcpy(copy + bv->bv_offset, dst, bv->bv_len);
1837 if (copy)
1838 dst = copy + bv->bv_offset;
1839 }
1840 for (off = 0; off < bv->bv_len; off += blksize) {
1841 sector_t trkid = recid;
1842 unsigned int recoffs = sector_div(trkid, blk_per_trk);
1843 rcmd = cmd;
1844 count = blksize;
1845 /* Locate record for cdl special block ? */
1846 if (private->uses_cdl && recid < 2*blk_per_trk) {
1847 if (dasd_eckd_cdl_special(blk_per_trk, recid)){
1848 rcmd |= 0x8;
1849 count = dasd_eckd_cdl_reclen(recid);
ec5883ab
HH
1850 if (count < blksize &&
1851 rq_data_dir(req) == READ)
1da177e4
LT
1852 memset(dst + count, 0xe5,
1853 blksize - count);
1854 }
1855 ccw[-1].flags |= CCW_FLAG_CC;
1856 locate_record(ccw++, LO_data++,
1857 trkid, recoffs + 1,
8e09f215 1858 1, rcmd, basedev, count);
1da177e4
LT
1859 }
1860 /* Locate record for standard blocks ? */
1861 if (private->uses_cdl && recid == 2*blk_per_trk) {
1862 ccw[-1].flags |= CCW_FLAG_CC;
1863 locate_record(ccw++, LO_data++,
1864 trkid, recoffs + 1,
1865 last_rec - recid + 1,
8e09f215 1866 cmd, basedev, count);
1da177e4
LT
1867 }
1868 /* Read/write ccw. */
1869 ccw[-1].flags |= CCW_FLAG_CC;
1870 ccw->cmd_code = rcmd;
1871 ccw->count = count;
1872 if (idal_is_needed(dst, blksize)) {
1873 ccw->cda = (__u32)(addr_t) idaws;
1874 ccw->flags = CCW_FLAG_IDA;
1875 idaws = idal_create_words(idaws, dst, blksize);
1876 } else {
1877 ccw->cda = (__u32)(addr_t) dst;
1878 ccw->flags = 0;
1879 }
1880 ccw++;
1881 dst += blksize;
1882 recid++;
1883 }
1884 }
13de227b
HS
1885 if (blk_noretry_request(req) ||
1886 block->base->features & DASD_FEATURE_FAILFAST)
1c01b8a5 1887 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
8e09f215
SW
1888 cqr->startdev = startdev;
1889 cqr->memdev = startdev;
1890 cqr->block = block;
1da177e4
LT
1891 cqr->expires = 5 * 60 * HZ; /* 5 minutes */
1892 cqr->lpm = private->path_data.ppm;
1893 cqr->retries = 256;
1894 cqr->buildclk = get_clock();
1895 cqr->status = DASD_CQR_FILLED;
1896 return cqr;
1897}
1898
f3eb5384
SW
1899static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
1900 struct dasd_device *startdev,
1901 struct dasd_block *block,
1902 struct request *req,
1903 sector_t first_rec,
1904 sector_t last_rec,
1905 sector_t first_trk,
1906 sector_t last_trk,
1907 unsigned int first_offs,
1908 unsigned int last_offs,
1909 unsigned int blk_per_trk,
1910 unsigned int blksize)
1911{
1912 struct dasd_eckd_private *private;
1913 unsigned long *idaws;
1914 struct dasd_ccw_req *cqr;
1915 struct ccw1 *ccw;
1916 struct req_iterator iter;
1917 struct bio_vec *bv;
1918 char *dst, *idaw_dst;
1919 unsigned int cidaw, cplength, datasize;
1920 unsigned int tlf;
1921 sector_t recid;
1922 unsigned char cmd;
1923 struct dasd_device *basedev;
1924 unsigned int trkcount, count, count_to_trk_end;
1925 unsigned int idaw_len, seg_len, part_len, len_to_track_end;
1926 unsigned char new_track, end_idaw;
1927 sector_t trkid;
1928 unsigned int recoffs;
1929
1930 basedev = block->base;
1931 private = (struct dasd_eckd_private *) basedev->private;
1932 if (rq_data_dir(req) == READ)
1933 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
1934 else if (rq_data_dir(req) == WRITE)
1935 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
1936 else
1937 return ERR_PTR(-EINVAL);
1938
1939 /* Track based I/O needs IDAWs for each page, and not just for
1940 * 64 bit addresses. We need additional idals for pages
1941 * that get filled from two tracks, so we use the number
1942 * of records as upper limit.
1943 */
1944 cidaw = last_rec - first_rec + 1;
1945 trkcount = last_trk - first_trk + 1;
1946
1947 /* 1x prefix + one read/write ccw per track */
1948 cplength = 1 + trkcount;
1949
1950 /* on 31-bit we need space for two 32 bit addresses per page
1951 * on 64-bit one 64 bit address
1952 */
1953 datasize = sizeof(struct PFX_eckd_data) +
1954 cidaw * sizeof(unsigned long long);
1955
1956 /* Allocate the ccw request. */
1957 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1958 cplength, datasize, startdev);
1959 if (IS_ERR(cqr))
1960 return cqr;
1961 ccw = cqr->cpaddr;
1962 /* transfer length factor: how many bytes to read from the last track */
1963 if (first_trk == last_trk)
1964 tlf = last_offs - first_offs + 1;
1965 else
1966 tlf = last_offs + 1;
1967 tlf *= blksize;
1968
1969 if (prefix_LRE(ccw++, cqr->data, first_trk,
1970 last_trk, cmd, basedev, startdev,
1971 1 /* format */, first_offs + 1,
1972 trkcount, blksize,
1973 tlf) == -EAGAIN) {
1974 /* Clock not in sync and XRC is enabled.
1975 * Try again later.
1976 */
1977 dasd_sfree_request(cqr, startdev);
1978 return ERR_PTR(-EAGAIN);
1979 }
1980
1981 /*
1982 * The translation of request into ccw programs must meet the
1983 * following conditions:
1984 * - all idaws but the first and the last must address full pages
1985 * (or 2K blocks on 31-bit)
1986 * - the scope of a ccw and it's idal ends with the track boundaries
1987 */
1988 idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
1989 recid = first_rec;
1990 new_track = 1;
1991 end_idaw = 0;
1992 len_to_track_end = 0;
1993 idaw_dst = 0;
1994 idaw_len = 0;
1995 rq_for_each_segment(bv, req, iter) {
1996 dst = page_address(bv->bv_page) + bv->bv_offset;
1997 seg_len = bv->bv_len;
1998 while (seg_len) {
1999 if (new_track) {
2000 trkid = recid;
2001 recoffs = sector_div(trkid, blk_per_trk);
2002 count_to_trk_end = blk_per_trk - recoffs;
2003 count = min((last_rec - recid + 1),
2004 (sector_t)count_to_trk_end);
2005 len_to_track_end = count * blksize;
2006 ccw[-1].flags |= CCW_FLAG_CC;
2007 ccw->cmd_code = cmd;
2008 ccw->count = len_to_track_end;
2009 ccw->cda = (__u32)(addr_t)idaws;
2010 ccw->flags = CCW_FLAG_IDA;
2011 ccw++;
2012 recid += count;
2013 new_track = 0;
2014 }
2015 /* If we start a new idaw, everything is fine and the
2016 * start of the new idaw is the start of this segment.
2017 * If we continue an idaw, we must make sure that the
2018 * current segment begins where the so far accumulated
2019 * idaw ends
2020 */
2021 if (!idaw_dst)
2022 idaw_dst = dst;
2023 if ((idaw_dst + idaw_len) != dst) {
2024 dasd_sfree_request(cqr, startdev);
2025 return ERR_PTR(-ERANGE);
2026 }
2027 part_len = min(seg_len, len_to_track_end);
2028 seg_len -= part_len;
2029 dst += part_len;
2030 idaw_len += part_len;
2031 len_to_track_end -= part_len;
2032 /* collected memory area ends on an IDA_BLOCK border,
2033 * -> create an idaw
2034 * idal_create_words will handle cases where idaw_len
2035 * is larger then IDA_BLOCK_SIZE
2036 */
2037 if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
2038 end_idaw = 1;
2039 /* We also need to end the idaw at track end */
2040 if (!len_to_track_end) {
2041 new_track = 1;
2042 end_idaw = 1;
2043 }
2044 if (end_idaw) {
2045 idaws = idal_create_words(idaws, idaw_dst,
2046 idaw_len);
2047 idaw_dst = 0;
2048 idaw_len = 0;
2049 end_idaw = 0;
2050 }
2051 }
2052 }
2053
2054 if (blk_noretry_request(req) ||
2055 block->base->features & DASD_FEATURE_FAILFAST)
2056 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2057 cqr->startdev = startdev;
2058 cqr->memdev = startdev;
2059 cqr->block = block;
2060 cqr->expires = 5 * 60 * HZ; /* 5 minutes */
2061 cqr->lpm = private->path_data.ppm;
2062 cqr->retries = 256;
2063 cqr->buildclk = get_clock();
2064 cqr->status = DASD_CQR_FILLED;
2065 return cqr;
2066}
2067
2068static int prepare_itcw(struct itcw *itcw,
2069 unsigned int trk, unsigned int totrk, int cmd,
2070 struct dasd_device *basedev,
2071 struct dasd_device *startdev,
2072 unsigned int rec_on_trk, int count,
2073 unsigned int blksize,
2074 unsigned int total_data_size,
2075 unsigned int tlf,
2076 unsigned int blk_per_trk)
2077{
2078 struct PFX_eckd_data pfxdata;
2079 struct dasd_eckd_private *basepriv, *startpriv;
2080 struct DE_eckd_data *dedata;
2081 struct LRE_eckd_data *lredata;
2082 struct dcw *dcw;
2083
2084 u32 begcyl, endcyl;
2085 u16 heads, beghead, endhead;
2086 u8 pfx_cmd;
2087
2088 int rc = 0;
2089 int sector = 0;
2090 int dn, d;
2091
2092
2093 /* setup prefix data */
2094 basepriv = (struct dasd_eckd_private *) basedev->private;
2095 startpriv = (struct dasd_eckd_private *) startdev->private;
2096 dedata = &pfxdata.define_extent;
2097 lredata = &pfxdata.locate_record;
2098
2099 memset(&pfxdata, 0, sizeof(pfxdata));
2100 pfxdata.format = 1; /* PFX with LRE */
2101 pfxdata.base_address = basepriv->ned->unit_addr;
2102 pfxdata.base_lss = basepriv->ned->ID;
2103 pfxdata.validity.define_extent = 1;
2104
2105 /* private uid is kept up to date, conf_data may be outdated */
2106 if (startpriv->uid.type != UA_BASE_DEVICE) {
2107 pfxdata.validity.verify_base = 1;
2108 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
2109 pfxdata.validity.hyper_pav = 1;
2110 }
2111
2112 switch (cmd) {
2113 case DASD_ECKD_CCW_READ_TRACK_DATA:
2114 dedata->mask.perm = 0x1;
2115 dedata->attributes.operation = basepriv->attrib.operation;
2116 dedata->blk_size = blksize;
2117 dedata->ga_extended |= 0x42;
2118 lredata->operation.orientation = 0x0;
2119 lredata->operation.operation = 0x0C;
2120 lredata->auxiliary.check_bytes = 0x01;
2121 pfx_cmd = DASD_ECKD_CCW_PFX_READ;
2122 break;
2123 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
2124 dedata->mask.perm = 0x02;
2125 dedata->attributes.operation = basepriv->attrib.operation;
2126 dedata->blk_size = blksize;
2127 rc = check_XRC_on_prefix(&pfxdata, basedev);
2128 dedata->ga_extended |= 0x42;
2129 lredata->operation.orientation = 0x0;
2130 lredata->operation.operation = 0x3F;
2131 lredata->extended_operation = 0x23;
2132 lredata->auxiliary.check_bytes = 0x2;
2133 pfx_cmd = DASD_ECKD_CCW_PFX;
2134 break;
2135 default:
2136 DBF_DEV_EVENT(DBF_ERR, basedev,
2137 "prepare itcw, unknown opcode 0x%x", cmd);
2138 BUG();
2139 break;
2140 }
2141 if (rc)
2142 return rc;
2143
2144 dedata->attributes.mode = 0x3; /* ECKD */
2145
2146 heads = basepriv->rdc_data.trk_per_cyl;
2147 begcyl = trk / heads;
2148 beghead = trk % heads;
2149 endcyl = totrk / heads;
2150 endhead = totrk % heads;
2151
2152 /* check for sequential prestage - enhance cylinder range */
2153 if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
2154 dedata->attributes.operation == DASD_SEQ_ACCESS) {
2155
2156 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
2157 endcyl += basepriv->attrib.nr_cyl;
2158 else
2159 endcyl = (basepriv->real_cyl - 1);
2160 }
2161
2162 set_ch_t(&dedata->beg_ext, begcyl, beghead);
2163 set_ch_t(&dedata->end_ext, endcyl, endhead);
2164
2165 dedata->ep_format = 0x20; /* records per track is valid */
2166 dedata->ep_rec_per_track = blk_per_trk;
2167
2168 if (rec_on_trk) {
2169 switch (basepriv->rdc_data.dev_type) {
2170 case 0x3390:
2171 dn = ceil_quot(blksize + 6, 232);
2172 d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
2173 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
2174 break;
2175 case 0x3380:
2176 d = 7 + ceil_quot(blksize + 12, 32);
2177 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
2178 break;
2179 }
2180 }
2181
2182 lredata->auxiliary.length_valid = 1;
2183 lredata->auxiliary.length_scope = 1;
2184 lredata->auxiliary.imbedded_ccw_valid = 1;
2185 lredata->length = tlf;
2186 lredata->imbedded_ccw = cmd;
2187 lredata->count = count;
2188 lredata->sector = sector;
2189 set_ch_t(&lredata->seek_addr, begcyl, beghead);
2190 lredata->search_arg.cyl = lredata->seek_addr.cyl;
2191 lredata->search_arg.head = lredata->seek_addr.head;
2192 lredata->search_arg.record = rec_on_trk;
2193
2194 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
2195 &pfxdata, sizeof(pfxdata), total_data_size);
2196
2197 return rc;
2198}
2199
2200static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2201 struct dasd_device *startdev,
2202 struct dasd_block *block,
2203 struct request *req,
2204 sector_t first_rec,
2205 sector_t last_rec,
2206 sector_t first_trk,
2207 sector_t last_trk,
2208 unsigned int first_offs,
2209 unsigned int last_offs,
2210 unsigned int blk_per_trk,
2211 unsigned int blksize)
2212{
2213 struct dasd_eckd_private *private;
2214 struct dasd_ccw_req *cqr;
2215 struct req_iterator iter;
2216 struct bio_vec *bv;
2217 char *dst;
2218 unsigned int trkcount, ctidaw;
2219 unsigned char cmd;
2220 struct dasd_device *basedev;
2221 unsigned int tlf;
2222 struct itcw *itcw;
2223 struct tidaw *last_tidaw = NULL;
2224 int itcw_op;
2225 size_t itcw_size;
2226
2227 basedev = block->base;
2228 private = (struct dasd_eckd_private *) basedev->private;
2229 if (rq_data_dir(req) == READ) {
2230 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
2231 itcw_op = ITCW_OP_READ;
2232 } else if (rq_data_dir(req) == WRITE) {
2233 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
2234 itcw_op = ITCW_OP_WRITE;
2235 } else
2236 return ERR_PTR(-EINVAL);
2237
2238 /* trackbased I/O needs address all memory via TIDAWs,
2239 * not just for 64 bit addresses. This allows us to map
2240 * each segment directly to one tidaw.
2241 */
2242 trkcount = last_trk - first_trk + 1;
2243 ctidaw = 0;
2244 rq_for_each_segment(bv, req, iter) {
2245 ++ctidaw;
2246 }
2247
2248 /* Allocate the ccw request. */
2249 itcw_size = itcw_calc_size(0, ctidaw, 0);
2250 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
2251 0, itcw_size, startdev);
2252 if (IS_ERR(cqr))
2253 return cqr;
2254
2255 cqr->cpmode = 1;
2256 cqr->startdev = startdev;
2257 cqr->memdev = startdev;
2258 cqr->block = block;
2259 cqr->expires = 100*HZ;
2260 cqr->buildclk = get_clock();
2261 cqr->status = DASD_CQR_FILLED;
2262 cqr->retries = 10;
2263
2264 /* transfer length factor: how many bytes to read from the last track */
2265 if (first_trk == last_trk)
2266 tlf = last_offs - first_offs + 1;
2267 else
2268 tlf = last_offs + 1;
2269 tlf *= blksize;
2270
2271 itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
2272 cqr->cpaddr = itcw_get_tcw(itcw);
2273
2274 if (prepare_itcw(itcw, first_trk, last_trk,
2275 cmd, basedev, startdev,
2276 first_offs + 1,
2277 trkcount, blksize,
2278 (last_rec - first_rec + 1) * blksize,
2279 tlf, blk_per_trk) == -EAGAIN) {
2280 /* Clock not in sync and XRC is enabled.
2281 * Try again later.
2282 */
2283 dasd_sfree_request(cqr, startdev);
2284 return ERR_PTR(-EAGAIN);
2285 }
2286
2287 /*
2288 * A tidaw can address 4k of memory, but must not cross page boundaries
2289 * We can let the block layer handle this by setting
2290 * blk_queue_segment_boundary to page boundaries and
2291 * blk_max_segment_size to page size when setting up the request queue.
2292 */
2293 rq_for_each_segment(bv, req, iter) {
2294 dst = page_address(bv->bv_page) + bv->bv_offset;
2295 last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
2296 if (IS_ERR(last_tidaw))
2297 return (struct dasd_ccw_req *)last_tidaw;
2298 }
2299
2300 last_tidaw->flags |= 0x80;
2301 itcw_finalize(itcw);
2302
2303 if (blk_noretry_request(req) ||
2304 block->base->features & DASD_FEATURE_FAILFAST)
2305 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2306 cqr->startdev = startdev;
2307 cqr->memdev = startdev;
2308 cqr->block = block;
2309 cqr->expires = 5 * 60 * HZ; /* 5 minutes */
2310 cqr->lpm = private->path_data.ppm;
2311 cqr->retries = 256;
2312 cqr->buildclk = get_clock();
2313 cqr->status = DASD_CQR_FILLED;
2314 return cqr;
2315}
2316
2317static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2318 struct dasd_block *block,
2319 struct request *req)
2320{
2321 int tpm, cmdrtd, cmdwtd;
2322 int use_prefix;
2323
2324 struct dasd_eckd_private *private;
2325 int fcx_in_css, fcx_in_gneq, fcx_in_features;
2326 struct dasd_device *basedev;
2327 sector_t first_rec, last_rec;
2328 sector_t first_trk, last_trk;
2329 unsigned int first_offs, last_offs;
2330 unsigned int blk_per_trk, blksize;
2331 int cdlspecial;
2332 struct dasd_ccw_req *cqr;
2333
2334 basedev = block->base;
2335 private = (struct dasd_eckd_private *) basedev->private;
2336
2337 /* Calculate number of blocks/records per track. */
2338 blksize = block->bp_block;
2339 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
2340 /* Calculate record id of first and last block. */
2341 first_rec = first_trk = req->sector >> block->s2b_shift;
2342 first_offs = sector_div(first_trk, blk_per_trk);
2343 last_rec = last_trk =
2344 (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
2345 last_offs = sector_div(last_trk, blk_per_trk);
2346 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
2347
2348 /* is transport mode supported ? */
2349 fcx_in_css = css_general_characteristics.fcx;
2350 fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
2351 fcx_in_features = private->features.feature[40] & 0x80;
2352 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
2353
2354 /* is read track data and write track data in command mode supported? */
2355 cmdrtd = private->features.feature[9] & 0x20;
2356 cmdwtd = private->features.feature[12] & 0x40;
2357 use_prefix = private->features.feature[8] & 0x01;
2358
2359 cqr = NULL;
2360 if (cdlspecial || dasd_page_cache) {
2361 /* do nothing, just fall through to the cmd mode single case */
2362 } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
2363 cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
2364 first_rec, last_rec,
2365 first_trk, last_trk,
2366 first_offs, last_offs,
2367 blk_per_trk, blksize);
2368 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
2369 cqr = NULL;
2370 } else if (use_prefix &&
2371 (((rq_data_dir(req) == READ) && cmdrtd) ||
2372 ((rq_data_dir(req) == WRITE) && cmdwtd))) {
2373 cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
2374 first_rec, last_rec,
2375 first_trk, last_trk,
2376 first_offs, last_offs,
2377 blk_per_trk, blksize);
2378 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
2379 cqr = NULL;
2380 }
2381 if (!cqr)
2382 cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
2383 first_rec, last_rec,
2384 first_trk, last_trk,
2385 first_offs, last_offs,
2386 blk_per_trk, blksize);
2387 return cqr;
2388}
2389
1da177e4
LT
2390static int
2391dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
2392{
2393 struct dasd_eckd_private *private;
2394 struct ccw1 *ccw;
5705f702 2395 struct req_iterator iter;
1da177e4
LT
2396 struct bio_vec *bv;
2397 char *dst, *cda;
2398 unsigned int blksize, blk_per_trk, off;
2399 sector_t recid;
5705f702 2400 int status;
1da177e4
LT
2401
2402 if (!dasd_page_cache)
2403 goto out;
8e09f215
SW
2404 private = (struct dasd_eckd_private *) cqr->block->base->private;
2405 blksize = cqr->block->bp_block;
1da177e4 2406 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
8e09f215 2407 recid = req->sector >> cqr->block->s2b_shift;
1da177e4
LT
2408 ccw = cqr->cpaddr;
2409 /* Skip over define extent & locate record. */
2410 ccw++;
2411 if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
2412 ccw++;
5705f702 2413 rq_for_each_segment(bv, req, iter) {
1da177e4
LT
2414 dst = page_address(bv->bv_page) + bv->bv_offset;
2415 for (off = 0; off < bv->bv_len; off += blksize) {
2416 /* Skip locate record. */
2417 if (private->uses_cdl && recid <= 2*blk_per_trk)
2418 ccw++;
2419 if (dst) {
2420 if (ccw->flags & CCW_FLAG_IDA)
2421 cda = *((char **)((addr_t) ccw->cda));
2422 else
2423 cda = (char *)((addr_t) ccw->cda);
2424 if (dst != cda) {
2425 if (rq_data_dir(req) == READ)
2426 memcpy(dst, cda, bv->bv_len);
2427 kmem_cache_free(dasd_page_cache,
2428 (void *)((addr_t)cda & PAGE_MASK));
2429 }
2430 dst = NULL;
2431 }
2432 ccw++;
2433 recid++;
2434 }
2435 }
2436out:
2437 status = cqr->status == DASD_CQR_DONE;
8e09f215 2438 dasd_sfree_request(cqr, cqr->memdev);
1da177e4
LT
2439 return status;
2440}
2441
8e09f215 2442/*
f3eb5384 2443 * Modify ccw/tcw in cqr so it can be started on a base device.
8e09f215
SW
2444 *
2445 * Note that this is not enough to restart the cqr!
2446 * Either reset cqr->startdev as well (summary unit check handling)
2447 * or restart via separate cqr (as in ERP handling).
2448 */
2449void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)
2450{
2451 struct ccw1 *ccw;
2452 struct PFX_eckd_data *pfxdata;
f3eb5384
SW
2453 struct tcw *tcw;
2454 struct tccb *tccb;
2455 struct dcw *dcw;
2456
2457 if (cqr->cpmode == 1) {
2458 tcw = cqr->cpaddr;
2459 tccb = tcw_get_tccb(tcw);
2460 dcw = (struct dcw *)&tccb->tca[0];
2461 pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
8e09f215
SW
2462 pfxdata->validity.verify_base = 0;
2463 pfxdata->validity.hyper_pav = 0;
f3eb5384
SW
2464 } else {
2465 ccw = cqr->cpaddr;
2466 pfxdata = cqr->data;
2467 if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
2468 pfxdata->validity.verify_base = 0;
2469 pfxdata->validity.hyper_pav = 0;
2470 }
8e09f215
SW
2471 }
2472}
2473
2474#define DASD_ECKD_CHANQ_MAX_SIZE 4
2475
2476static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base,
2477 struct dasd_block *block,
2478 struct request *req)
2479{
2480 struct dasd_eckd_private *private;
2481 struct dasd_device *startdev;
2482 unsigned long flags;
2483 struct dasd_ccw_req *cqr;
2484
2485 startdev = dasd_alias_get_start_dev(base);
2486 if (!startdev)
2487 startdev = base;
2488 private = (struct dasd_eckd_private *) startdev->private;
2489 if (private->count >= DASD_ECKD_CHANQ_MAX_SIZE)
2490 return ERR_PTR(-EBUSY);
2491
2492 spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags);
2493 private->count++;
2494 cqr = dasd_eckd_build_cp(startdev, block, req);
2495 if (IS_ERR(cqr))
2496 private->count--;
2497 spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags);
2498 return cqr;
2499}
2500
2501static int dasd_eckd_free_alias_cp(struct dasd_ccw_req *cqr,
2502 struct request *req)
2503{
2504 struct dasd_eckd_private *private;
2505 unsigned long flags;
2506
2507 spin_lock_irqsave(get_ccwdev_lock(cqr->memdev->cdev), flags);
2508 private = (struct dasd_eckd_private *) cqr->memdev->private;
2509 private->count--;
2510 spin_unlock_irqrestore(get_ccwdev_lock(cqr->memdev->cdev), flags);
2511 return dasd_eckd_free_cp(cqr, req);
2512}
2513
1da177e4
LT
2514static int
2515dasd_eckd_fill_info(struct dasd_device * device,
2516 struct dasd_information2_t * info)
2517{
2518 struct dasd_eckd_private *private;
2519
2520 private = (struct dasd_eckd_private *) device->private;
2521 info->label_block = 2;
2522 info->FBA_layout = private->uses_cdl ? 0 : 1;
2523 info->format = private->uses_cdl ? DASD_FORMAT_CDL : DASD_FORMAT_LDL;
2524 info->characteristics_size = sizeof(struct dasd_eckd_characteristics);
2525 memcpy(info->characteristics, &private->rdc_data,
2526 sizeof(struct dasd_eckd_characteristics));
4abb08c2
SW
2527 info->confdata_size = min((unsigned long)private->conf_len,
2528 sizeof(info->configuration_data));
2529 memcpy(info->configuration_data, private->conf_data,
2530 info->confdata_size);
1da177e4
LT
2531 return 0;
2532}
2533
2534/*
2535 * SECTION: ioctl functions for eckd devices.
2536 */
2537
2538/*
2539 * Release device ioctl.
138c014d 2540 * Buils a channel programm to releases a prior reserved
1da177e4
LT
2541 * (see dasd_eckd_reserve) device.
2542 */
2543static int
1107ccfb 2544dasd_eckd_release(struct dasd_device *device)
1da177e4 2545{
1da177e4
LT
2546 struct dasd_ccw_req *cqr;
2547 int rc;
f3eb5384 2548 struct ccw1 *ccw;
1da177e4
LT
2549
2550 if (!capable(CAP_SYS_ADMIN))
2551 return -EACCES;
2552
1da177e4
LT
2553 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
2554 1, 32, device);
2555 if (IS_ERR(cqr)) {
2556 DEV_MESSAGE(KERN_WARNING, device, "%s",
2557 "Could not allocate initialization request");
2558 return PTR_ERR(cqr);
2559 }
f3eb5384
SW
2560 ccw = cqr->cpaddr;
2561 ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
2562 ccw->flags |= CCW_FLAG_SLI;
2563 ccw->count = 32;
2564 ccw->cda = (__u32)(addr_t) cqr->data;
8e09f215
SW
2565 cqr->startdev = device;
2566 cqr->memdev = device;
1da177e4 2567 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
1c01b8a5 2568 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
336c340b 2569 cqr->retries = 2; /* set retry counter to enable basic ERP */
1da177e4
LT
2570 cqr->expires = 2 * HZ;
2571 cqr->buildclk = get_clock();
2572 cqr->status = DASD_CQR_FILLED;
2573
2574 rc = dasd_sleep_on_immediatly(cqr);
2575
8e09f215 2576 dasd_sfree_request(cqr, cqr->memdev);
1da177e4
LT
2577 return rc;
2578}
2579
2580/*
2581 * Reserve device ioctl.
2582 * Options are set to 'synchronous wait for interrupt' and
138c014d
HH
2583 * 'timeout the request'. This leads to a terminate IO if
2584 * the interrupt is outstanding for a certain time.
1da177e4
LT
2585 */
2586static int
1107ccfb 2587dasd_eckd_reserve(struct dasd_device *device)
1da177e4 2588{
1da177e4
LT
2589 struct dasd_ccw_req *cqr;
2590 int rc;
f3eb5384 2591 struct ccw1 *ccw;
1da177e4
LT
2592
2593 if (!capable(CAP_SYS_ADMIN))
2594 return -EACCES;
2595
1da177e4
LT
2596 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
2597 1, 32, device);
2598 if (IS_ERR(cqr)) {
2599 DEV_MESSAGE(KERN_WARNING, device, "%s",
2600 "Could not allocate initialization request");
2601 return PTR_ERR(cqr);
2602 }
f3eb5384
SW
2603 ccw = cqr->cpaddr;
2604 ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
2605 ccw->flags |= CCW_FLAG_SLI;
2606 ccw->count = 32;
2607 ccw->cda = (__u32)(addr_t) cqr->data;
8e09f215
SW
2608 cqr->startdev = device;
2609 cqr->memdev = device;
1da177e4 2610 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
1c01b8a5 2611 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
336c340b 2612 cqr->retries = 2; /* set retry counter to enable basic ERP */
1da177e4
LT
2613 cqr->expires = 2 * HZ;
2614 cqr->buildclk = get_clock();
2615 cqr->status = DASD_CQR_FILLED;
2616
2617 rc = dasd_sleep_on_immediatly(cqr);
2618
8e09f215 2619 dasd_sfree_request(cqr, cqr->memdev);
1da177e4
LT
2620 return rc;
2621}
2622
2623/*
2624 * Steal lock ioctl - unconditional reserve device.
138c014d 2625 * Buils a channel programm to break a device's reservation.
1da177e4
LT
2626 * (unconditional reserve)
2627 */
2628static int
1107ccfb 2629dasd_eckd_steal_lock(struct dasd_device *device)
1da177e4 2630{
1da177e4
LT
2631 struct dasd_ccw_req *cqr;
2632 int rc;
f3eb5384 2633 struct ccw1 *ccw;
1da177e4
LT
2634
2635 if (!capable(CAP_SYS_ADMIN))
2636 return -EACCES;
2637
1da177e4
LT
2638 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
2639 1, 32, device);
2640 if (IS_ERR(cqr)) {
2641 DEV_MESSAGE(KERN_WARNING, device, "%s",
2642 "Could not allocate initialization request");
2643 return PTR_ERR(cqr);
2644 }
f3eb5384
SW
2645 ccw = cqr->cpaddr;
2646 ccw->cmd_code = DASD_ECKD_CCW_SLCK;
2647 ccw->flags |= CCW_FLAG_SLI;
2648 ccw->count = 32;
2649 ccw->cda = (__u32)(addr_t) cqr->data;
8e09f215
SW
2650 cqr->startdev = device;
2651 cqr->memdev = device;
1da177e4 2652 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
1c01b8a5 2653 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
336c340b 2654 cqr->retries = 2; /* set retry counter to enable basic ERP */
1da177e4
LT
2655 cqr->expires = 2 * HZ;
2656 cqr->buildclk = get_clock();
2657 cqr->status = DASD_CQR_FILLED;
2658
2659 rc = dasd_sleep_on_immediatly(cqr);
2660
8e09f215 2661 dasd_sfree_request(cqr, cqr->memdev);
1da177e4
LT
2662 return rc;
2663}
2664
2665/*
2666 * Read performance statistics
2667 */
2668static int
1107ccfb 2669dasd_eckd_performance(struct dasd_device *device, void __user *argp)
1da177e4 2670{
1da177e4
LT
2671 struct dasd_psf_prssd_data *prssdp;
2672 struct dasd_rssd_perf_stats_t *stats;
2673 struct dasd_ccw_req *cqr;
2674 struct ccw1 *ccw;
2675 int rc;
2676
1da177e4
LT
2677 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
2678 1 /* PSF */ + 1 /* RSSD */ ,
8e09f215
SW
2679 (sizeof(struct dasd_psf_prssd_data) +
2680 sizeof(struct dasd_rssd_perf_stats_t)),
1da177e4
LT
2681 device);
2682 if (IS_ERR(cqr)) {
2683 DEV_MESSAGE(KERN_WARNING, device, "%s",
2684 "Could not allocate initialization request");
2685 return PTR_ERR(cqr);
2686 }
8e09f215
SW
2687 cqr->startdev = device;
2688 cqr->memdev = device;
1da177e4
LT
2689 cqr->retries = 0;
2690 cqr->expires = 10 * HZ;
2691
2692 /* Prepare for Read Subsystem Data */
2693 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
8e09f215 2694 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
1da177e4 2695 prssdp->order = PSF_ORDER_PRSSD;
5d67d164 2696 prssdp->suborder = 0x01; /* Performance Statistics */
1da177e4
LT
2697 prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */
2698
2699 ccw = cqr->cpaddr;
2700 ccw->cmd_code = DASD_ECKD_CCW_PSF;
8e09f215 2701 ccw->count = sizeof(struct dasd_psf_prssd_data);
1da177e4
LT
2702 ccw->flags |= CCW_FLAG_CC;
2703 ccw->cda = (__u32)(addr_t) prssdp;
2704
2705 /* Read Subsystem Data - Performance Statistics */
2706 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
8e09f215 2707 memset(stats, 0, sizeof(struct dasd_rssd_perf_stats_t));
1da177e4
LT
2708
2709 ccw++;
2710 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
8e09f215 2711 ccw->count = sizeof(struct dasd_rssd_perf_stats_t);
1da177e4
LT
2712 ccw->cda = (__u32)(addr_t) stats;
2713
2714 cqr->buildclk = get_clock();
2715 cqr->status = DASD_CQR_FILLED;
2716 rc = dasd_sleep_on(cqr);
2717 if (rc == 0) {
1da177e4
LT
2718 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
2719 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
1107ccfb
CH
2720 if (copy_to_user(argp, stats,
2721 sizeof(struct dasd_rssd_perf_stats_t)))
2722 rc = -EFAULT;
1da177e4 2723 }
8e09f215 2724 dasd_sfree_request(cqr, cqr->memdev);
1da177e4
LT
2725 return rc;
2726}
2727
2728/*
2729 * Get attributes (cache operations)
2730 * Returnes the cache attributes used in Define Extend (DE).
2731 */
2732static int
1107ccfb 2733dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp)
1da177e4 2734{
1107ccfb
CH
2735 struct dasd_eckd_private *private =
2736 (struct dasd_eckd_private *)device->private;
2737 struct attrib_data_t attrib = private->attrib;
1da177e4
LT
2738 int rc;
2739
2740 if (!capable(CAP_SYS_ADMIN))
2741 return -EACCES;
1107ccfb 2742 if (!argp)
1da177e4
LT
2743 return -EINVAL;
2744
1107ccfb
CH
2745 rc = 0;
2746 if (copy_to_user(argp, (long *) &attrib,
8e09f215 2747 sizeof(struct attrib_data_t)))
1107ccfb 2748 rc = -EFAULT;
1da177e4
LT
2749
2750 return rc;
2751}
2752
2753/*
2754 * Set attributes (cache operations)
2755 * Stores the attributes for cache operation to be used in Define Extend (DE).
2756 */
2757static int
1107ccfb 2758dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
1da177e4 2759{
1107ccfb
CH
2760 struct dasd_eckd_private *private =
2761 (struct dasd_eckd_private *)device->private;
1da177e4
LT
2762 struct attrib_data_t attrib;
2763
2764 if (!capable(CAP_SYS_ADMIN))
2765 return -EACCES;
1107ccfb 2766 if (!argp)
1da177e4
LT
2767 return -EINVAL;
2768
1107ccfb 2769 if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t)))
1da177e4 2770 return -EFAULT;
1da177e4
LT
2771 private->attrib = attrib;
2772
2773 DEV_MESSAGE(KERN_INFO, device,
2774 "cache operation mode set to %x (%i cylinder prestage)",
2775 private->attrib.operation, private->attrib.nr_cyl);
2776 return 0;
2777}
2778
ab1d848f
NH
2779/*
2780 * Issue syscall I/O to EMC Symmetrix array.
2781 * CCWs are PSF and RSSD
2782 */
2783static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2784{
2785 struct dasd_symmio_parms usrparm;
2786 char *psf_data, *rssd_result;
2787 struct dasd_ccw_req *cqr;
2788 struct ccw1 *ccw;
2789 int rc;
2790
2791 /* Copy parms from caller */
2792 rc = -EFAULT;
2793 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
2794 goto out;
2795#ifndef CONFIG_64BIT
2796 /* Make sure pointers are sane even on 31 bit. */
2797 if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) {
2798 rc = -EINVAL;
2799 goto out;
2800 }
2801#endif
2802 /* alloc I/O data area */
2803 psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);
2804 rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);
2805 if (!psf_data || !rssd_result) {
2806 rc = -ENOMEM;
2807 goto out_free;
2808 }
2809
2810 /* get syscall header from user space */
2811 rc = -EFAULT;
2812 if (copy_from_user(psf_data,
2813 (void __user *)(unsigned long) usrparm.psf_data,
2814 usrparm.psf_data_len))
2815 goto out_free;
2816
2817 /* sanity check on syscall header */
2818 if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
2819 rc = -EINVAL;
2820 goto out_free;
2821 }
2822
2823 /* setup CCWs for PSF + RSSD */
2824 cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
2825 if (IS_ERR(cqr)) {
2826 DEV_MESSAGE(KERN_WARNING, device, "%s",
2827 "Could not allocate initialization request");
2828 rc = PTR_ERR(cqr);
2829 goto out_free;
2830 }
2831
2832 cqr->startdev = device;
2833 cqr->memdev = device;
2834 cqr->retries = 3;
2835 cqr->expires = 10 * HZ;
2836 cqr->buildclk = get_clock();
2837 cqr->status = DASD_CQR_FILLED;
2838
2839 /* Build the ccws */
2840 ccw = cqr->cpaddr;
2841
2842 /* PSF ccw */
2843 ccw->cmd_code = DASD_ECKD_CCW_PSF;
2844 ccw->count = usrparm.psf_data_len;
2845 ccw->flags |= CCW_FLAG_CC;
2846 ccw->cda = (__u32)(addr_t) psf_data;
2847
2848 ccw++;
2849
2850 /* RSSD ccw */
2851 ccw->cmd_code = DASD_ECKD_CCW_RSSD;
2852 ccw->count = usrparm.rssd_result_len;
2853 ccw->flags = CCW_FLAG_SLI ;
2854 ccw->cda = (__u32)(addr_t) rssd_result;
2855
2856 rc = dasd_sleep_on(cqr);
2857 if (rc)
2858 goto out_sfree;
2859
2860 rc = -EFAULT;
2861 if (copy_to_user((void __user *)(unsigned long) usrparm.rssd_result,
2862 rssd_result, usrparm.rssd_result_len))
2863 goto out_sfree;
2864 rc = 0;
2865
2866out_sfree:
2867 dasd_sfree_request(cqr, cqr->memdev);
2868out_free:
2869 kfree(rssd_result);
2870 kfree(psf_data);
2871out:
2872 DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc);
2873 return rc;
2874}
2875
1107ccfb 2876static int
8e09f215 2877dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
1107ccfb 2878{
8e09f215
SW
2879 struct dasd_device *device = block->base;
2880
1107ccfb
CH
2881 switch (cmd) {
2882 case BIODASDGATTR:
2883 return dasd_eckd_get_attrib(device, argp);
2884 case BIODASDSATTR:
2885 return dasd_eckd_set_attrib(device, argp);
2886 case BIODASDPSRD:
2887 return dasd_eckd_performance(device, argp);
2888 case BIODASDRLSE:
2889 return dasd_eckd_release(device);
2890 case BIODASDRSRV:
2891 return dasd_eckd_reserve(device);
2892 case BIODASDSLCK:
2893 return dasd_eckd_steal_lock(device);
ab1d848f
NH
2894 case BIODASDSYMMIO:
2895 return dasd_symm_io(device, argp);
1107ccfb
CH
2896 default:
2897 return -ENOIOCTLCMD;
2898 }
2899}
2900
445b5b49
HH
2901/*
2902 * Dump the range of CCWs into 'page' buffer
2903 * and return number of printed chars.
2904 */
4d284cac 2905static int
445b5b49
HH
2906dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
2907{
2908 int len, count;
2909 char *datap;
2910
2911 len = 0;
2912 while (from <= to) {
2913 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
2914 " CCW %p: %08X %08X DAT:",
2915 from, ((int *) from)[0], ((int *) from)[1]);
2916
2917 /* get pointer to data (consider IDALs) */
2918 if (from->flags & CCW_FLAG_IDA)
2919 datap = (char *) *((addr_t *) (addr_t) from->cda);
2920 else
2921 datap = (char *) ((addr_t) from->cda);
2922
2923 /* dump data (max 32 bytes) */
2924 for (count = 0; count < from->count && count < 32; count++) {
2925 if (count % 8 == 0) len += sprintf(page + len, " ");
2926 if (count % 4 == 0) len += sprintf(page + len, " ");
2927 len += sprintf(page + len, "%02x", datap[count]);
2928 }
2929 len += sprintf(page + len, "\n");
2930 from++;
2931 }
2932 return len;
2933}
2934
1da177e4
LT
2935/*
2936 * Print sense data and related channel program.
2937 * Parts are printed because printk buffer is only 1024 bytes.
2938 */
f3eb5384 2939static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
8e09f215 2940 struct dasd_ccw_req *req, struct irb *irb)
1da177e4
LT
2941{
2942 char *page;
445b5b49
HH
2943 struct ccw1 *first, *last, *fail, *from, *to;
2944 int len, sl, sct;
1da177e4
LT
2945
2946 page = (char *) get_zeroed_page(GFP_ATOMIC);
2947 if (page == NULL) {
2948 DEV_MESSAGE(KERN_ERR, device, " %s",
2949 "No memory to dump sense data");
2950 return;
2951 }
445b5b49
HH
2952 /* dump the sense data */
2953 len = sprintf(page, KERN_ERR PRINTK_HEADER
1da177e4 2954 " I/O status report for device %s:\n",
2a0217d5 2955 dev_name(&device->cdev->dev));
1da177e4
LT
2956 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
2957 " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
f3eb5384 2958 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
1da177e4
LT
2959 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
2960 " device %s: Failing CCW: %p\n",
2a0217d5 2961 dev_name(&device->cdev->dev),
23d805b6 2962 (void *) (addr_t) irb->scsw.cmd.cpa);
1da177e4
LT
2963 if (irb->esw.esw0.erw.cons) {
2964 for (sl = 0; sl < 4; sl++) {
2965 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
2966 " Sense(hex) %2d-%2d:",
2967 (8 * sl), ((8 * sl) + 7));
2968
2969 for (sct = 0; sct < 8; sct++) {
2970 len += sprintf(page + len, " %02x",
2971 irb->ecw[8 * sl + sct]);
2972 }
2973 len += sprintf(page + len, "\n");
2974 }
2975
2976 if (irb->ecw[27] & DASD_SENSE_BIT_0) {
2977 /* 24 Byte Sense Data */
445b5b49
HH
2978 sprintf(page + len, KERN_ERR PRINTK_HEADER
2979 " 24 Byte: %x MSG %x, "
2980 "%s MSGb to SYSOP\n",
2981 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
2982 irb->ecw[1] & 0x10 ? "" : "no");
1da177e4
LT
2983 } else {
2984 /* 32 Byte Sense Data */
445b5b49
HH
2985 sprintf(page + len, KERN_ERR PRINTK_HEADER
2986 " 32 Byte: Format: %x "
2987 "Exception class %x\n",
2988 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
1da177e4
LT
2989 }
2990 } else {
445b5b49
HH
2991 sprintf(page + len, KERN_ERR PRINTK_HEADER
2992 " SORRY - NO VALID SENSE AVAILABLE\n");
1da177e4 2993 }
445b5b49
HH
2994 printk("%s", page);
2995
8e09f215
SW
2996 if (req) {
2997 /* req == NULL for unsolicited interrupts */
2998 /* dump the Channel Program (max 140 Bytes per line) */
2999 /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */
3000 first = req->cpaddr;
3001 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
3002 to = min(first + 6, last);
3003 len = sprintf(page, KERN_ERR PRINTK_HEADER
3004 " Related CP in req: %p\n", req);
3005 dasd_eckd_dump_ccw_range(first, to, page + len);
3006 printk("%s", page);
1da177e4 3007
8e09f215
SW
3008 /* print failing CCW area (maximum 4) */
3009 /* scsw->cda is either valid or zero */
3010 len = 0;
3011 from = ++to;
23d805b6
PO
3012 fail = (struct ccw1 *)(addr_t)
3013 irb->scsw.cmd.cpa; /* failing CCW */
8e09f215
SW
3014 if (from < fail - 2) {
3015 from = fail - 2; /* there is a gap - print header */
3016 len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n");
3017 }
3018 to = min(fail + 1, last);
3019 len += dasd_eckd_dump_ccw_range(from, to, page + len);
3020
3021 /* print last CCWs (maximum 2) */
3022 from = max(from, ++to);
3023 if (from < last - 1) {
3024 from = last - 1; /* there is a gap - print header */
3025 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
3026 }
3027 len += dasd_eckd_dump_ccw_range(from, last, page + len);
3028 if (len > 0)
3029 printk("%s", page);
1da177e4 3030 }
1da177e4
LT
3031 free_page((unsigned long) page);
3032}
3033
f3eb5384
SW
3034
3035/*
3036 * Print sense data from a tcw.
3037 */
3038static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3039 struct dasd_ccw_req *req, struct irb *irb)
3040{
3041 char *page;
3042 int len, sl, sct, residual;
3043
3044 struct tsb *tsb;
3045 u8 *sense;
3046
3047
3048 page = (char *) get_zeroed_page(GFP_ATOMIC);
3049 if (page == NULL) {
3050 DEV_MESSAGE(KERN_ERR, device, " %s",
3051 "No memory to dump sense data");
3052 return;
3053 }
3054 /* dump the sense data */
3055 len = sprintf(page, KERN_ERR PRINTK_HEADER
3056 " I/O status report for device %s:\n",
3057 dev_name(&device->cdev->dev));
3058 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3059 " in req: %p CS: 0x%02X DS: 0x%02X "
3060 "fcxs: 0x%02X schxs: 0x%02X\n", req,
3061 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
3062 irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
3063 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3064 " device %s: Failing TCW: %p\n",
3065 dev_name(&device->cdev->dev),
3066 (void *) (addr_t) irb->scsw.tm.tcw);
3067
3068 tsb = NULL;
3069 sense = NULL;
3070 if (irb->scsw.tm.tcw)
3071 tsb = tcw_get_tsb(
3072 (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
3073
3074 if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
3075 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3076 " tsb->length %d\n", tsb->length);
3077 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3078 " tsb->flags %x\n", tsb->flags);
3079 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3080 " tsb->dcw_offset %d\n", tsb->dcw_offset);
3081 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3082 " tsb->count %d\n", tsb->count);
3083 residual = tsb->count - 28;
3084 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3085 " residual %d\n", residual);
3086
3087 switch (tsb->flags & 0x07) {
3088 case 1: /* tsa_iostat */
3089 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3090 " tsb->tsa.iostat.dev_time %d\n",
3091 tsb->tsa.iostat.dev_time);
3092 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3093 " tsb->tsa.iostat.def_time %d\n",
3094 tsb->tsa.iostat.def_time);
3095 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3096 " tsb->tsa.iostat.queue_time %d\n",
3097 tsb->tsa.iostat.queue_time);
3098 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3099 " tsb->tsa.iostat.dev_busy_time %d\n",
3100 tsb->tsa.iostat.dev_busy_time);
3101 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3102 " tsb->tsa.iostat.dev_act_time %d\n",
3103 tsb->tsa.iostat.dev_act_time);
3104 sense = tsb->tsa.iostat.sense;
3105 break;
3106 case 2: /* ts_ddpc */
3107 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3108 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
3109 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3110 " tsb->tsa.ddpc.rcq: ");
3111 for (sl = 0; sl < 16; sl++) {
3112 for (sct = 0; sct < 8; sct++) {
3113 len += sprintf(page + len, " %02x",
3114 tsb->tsa.ddpc.rcq[sl]);
3115 }
3116 len += sprintf(page + len, "\n");
3117 }
3118 sense = tsb->tsa.ddpc.sense;
3119 break;
3120 case 3: /* tsa_intrg */
3121 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3122 " tsb->tsa.intrg.: not supportet yet \n");
3123 break;
3124 }
3125
3126 if (sense) {
3127 for (sl = 0; sl < 4; sl++) {
3128 len += sprintf(page + len,
3129 KERN_ERR PRINTK_HEADER
3130 " Sense(hex) %2d-%2d:",
3131 (8 * sl), ((8 * sl) + 7));
3132 for (sct = 0; sct < 8; sct++) {
3133 len += sprintf(page + len, " %02x",
3134 sense[8 * sl + sct]);
3135 }
3136 len += sprintf(page + len, "\n");
3137 }
3138
3139 if (sense[27] & DASD_SENSE_BIT_0) {
3140 /* 24 Byte Sense Data */
3141 sprintf(page + len, KERN_ERR PRINTK_HEADER
3142 " 24 Byte: %x MSG %x, "
3143 "%s MSGb to SYSOP\n",
3144 sense[7] >> 4, sense[7] & 0x0f,
3145 sense[1] & 0x10 ? "" : "no");
3146 } else {
3147 /* 32 Byte Sense Data */
3148 sprintf(page + len, KERN_ERR PRINTK_HEADER
3149 " 32 Byte: Format: %x "
3150 "Exception class %x\n",
3151 sense[6] & 0x0f, sense[22] >> 4);
3152 }
3153 } else {
3154 sprintf(page + len, KERN_ERR PRINTK_HEADER
3155 " SORRY - NO VALID SENSE AVAILABLE\n");
3156 }
3157 } else {
3158 sprintf(page + len, KERN_ERR PRINTK_HEADER
3159 " SORRY - NO TSB DATA AVAILABLE\n");
3160 }
3161 printk("%s", page);
3162 free_page((unsigned long) page);
3163}
3164
3165static void dasd_eckd_dump_sense(struct dasd_device *device,
3166 struct dasd_ccw_req *req, struct irb *irb)
3167{
3168 if (req && scsw_is_tm(&req->irb.scsw))
3169 dasd_eckd_dump_sense_tcw(device, req, irb);
3170 else
3171 dasd_eckd_dump_sense_ccw(device, req, irb);
3172}
3173
3174
1da177e4
LT
3175/*
3176 * max_blocks is dependent on the amount of storage that is available
3177 * in the static io buffer for each device. Currently each device has
3178 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
3179 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
3180 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
3181 * addition we have one define extent ccw + 16 bytes of data and one
3182 * locate record ccw + 16 bytes of data. That makes:
3183 * (8192 - 24 - 136 - 8 - 16 - 8 - 16) / 16 = 499 blocks at maximum.
3184 * We want to fit two into the available memory so that we can immediately
3185 * start the next request if one finishes off. That makes 249.5 blocks
3186 * for one request. Give a little safety and the result is 240.
3187 */
3188static struct dasd_discipline dasd_eckd_discipline = {
3189 .owner = THIS_MODULE,
3190 .name = "ECKD",
3191 .ebcname = "ECKD",
3192 .max_blocks = 240,
3193 .check_device = dasd_eckd_check_characteristics,
8e09f215 3194 .uncheck_device = dasd_eckd_uncheck_device,
1da177e4 3195 .do_analysis = dasd_eckd_do_analysis,
8e09f215
SW
3196 .ready_to_online = dasd_eckd_ready_to_online,
3197 .online_to_ready = dasd_eckd_online_to_ready,
1da177e4
LT
3198 .fill_geometry = dasd_eckd_fill_geometry,
3199 .start_IO = dasd_start_IO,
3200 .term_IO = dasd_term_IO,
8e09f215 3201 .handle_terminated_request = dasd_eckd_handle_terminated_request,
1da177e4 3202 .format_device = dasd_eckd_format_device,
1da177e4
LT
3203 .erp_action = dasd_eckd_erp_action,
3204 .erp_postaction = dasd_eckd_erp_postaction,
8e09f215
SW
3205 .handle_unsolicited_interrupt = dasd_eckd_handle_unsolicited_interrupt,
3206 .build_cp = dasd_eckd_build_alias_cp,
3207 .free_cp = dasd_eckd_free_alias_cp,
1da177e4
LT
3208 .dump_sense = dasd_eckd_dump_sense,
3209 .fill_info = dasd_eckd_fill_info,
1107ccfb 3210 .ioctl = dasd_eckd_ioctl,
1da177e4
LT
3211};
3212
3213static int __init
3214dasd_eckd_init(void)
3215{
1da177e4 3216 ASCEBC(dasd_eckd_discipline.ebcname, 4);
40545573 3217 return ccw_driver_register(&dasd_eckd_driver);
1da177e4
LT
3218}
3219
3220static void __exit
3221dasd_eckd_cleanup(void)
3222{
3223 ccw_driver_unregister(&dasd_eckd_driver);
1da177e4
LT
3224}
3225
3226module_init(dasd_eckd_init);
3227module_exit(dasd_eckd_cleanup);