dasd_eckd.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723
  1. /*
  2. * File...........: linux/drivers/s390/block/dasd_eckd.c
  3. * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  4. * Horst Hummel <Horst.Hummel@de.ibm.com>
  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
  9. *
  10. * $Revision: 1.71 $
  11. */
  12. #include <linux/config.h>
  13. #include <linux/stddef.h>
  14. #include <linux/kernel.h>
  15. #include <linux/slab.h>
  16. #include <linux/hdreg.h> /* HDIO_GETGEO */
  17. #include <linux/bio.h>
  18. #include <linux/module.h>
  19. #include <linux/init.h>
  20. #include <asm/debug.h>
  21. #include <asm/idals.h>
  22. #include <asm/ebcdic.h>
  23. #include <asm/io.h>
  24. #include <asm/todclk.h>
  25. #include <asm/uaccess.h>
  26. #include <asm/ccwdev.h>
  27. #include "dasd_int.h"
  28. #include "dasd_eckd.h"
  29. #ifdef PRINTK_HEADER
  30. #undef PRINTK_HEADER
  31. #endif /* PRINTK_HEADER */
  32. #define PRINTK_HEADER "dasd(eckd):"
  33. #define ECKD_C0(i) (i->home_bytes)
  34. #define ECKD_F(i) (i->formula)
  35. #define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):\
  36. (i->factors.f_0x02.f1))
  37. #define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):\
  38. (i->factors.f_0x02.f2))
  39. #define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):\
  40. (i->factors.f_0x02.f3))
  41. #define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0)
  42. #define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0)
  43. #define ECKD_F6(i) (i->factor6)
  44. #define ECKD_F7(i) (i->factor7)
  45. #define ECKD_F8(i) (i->factor8)
  46. MODULE_LICENSE("GPL");
  47. static struct dasd_discipline dasd_eckd_discipline;
  48. struct dasd_eckd_private {
  49. struct dasd_eckd_characteristics rdc_data;
  50. struct dasd_eckd_confdata conf_data;
  51. struct dasd_eckd_path path_data;
  52. struct eckd_count count_area[5];
  53. int init_cqr_status;
  54. int uses_cdl;
  55. struct attrib_data_t attrib; /* e.g. cache operations */
  56. };
  57. /* The ccw bus type uses this table to find devices that it sends to
  58. * dasd_eckd_probe */
  59. static struct ccw_device_id dasd_eckd_ids[] = {
  60. { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), driver_info: 0x1},
  61. { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), driver_info: 0x2},
  62. { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), driver_info: 0x3},
  63. { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), driver_info: 0x4},
  64. { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), driver_info: 0x5},
  65. { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), driver_info: 0x6},
  66. { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3390, 0), driver_info: 0x7},
  67. { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3380, 0), driver_info: 0x8},
  68. { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3390, 0), driver_info: 0x9},
  69. { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3380, 0), driver_info: 0xa},
  70. { /* end of list */ },
  71. };
  72. MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);
  73. static struct ccw_driver dasd_eckd_driver; /* see below */
  74. /* initial attempt at a probe function. this can be simplified once
  75. * the other detection code is gone */
  76. static int
  77. dasd_eckd_probe (struct ccw_device *cdev)
  78. {
  79. int ret;
  80. ret = dasd_generic_probe (cdev, &dasd_eckd_discipline);
  81. if (ret)
  82. return ret;
  83. ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE);
  84. return 0;
  85. }
  86. static int
  87. dasd_eckd_set_online(struct ccw_device *cdev)
  88. {
  89. return dasd_generic_set_online (cdev, &dasd_eckd_discipline);
  90. }
  91. static struct ccw_driver dasd_eckd_driver = {
  92. .name = "dasd-eckd",
  93. .owner = THIS_MODULE,
  94. .ids = dasd_eckd_ids,
  95. .probe = dasd_eckd_probe,
  96. .remove = dasd_generic_remove,
  97. .set_offline = dasd_generic_set_offline,
  98. .set_online = dasd_eckd_set_online,
  99. .notify = dasd_generic_notify,
  100. };
  101. static const int sizes_trk0[] = { 28, 148, 84 };
  102. #define LABEL_SIZE 140
  103. static inline unsigned int
  104. round_up_multiple(unsigned int no, unsigned int mult)
  105. {
  106. int rem = no % mult;
  107. return (rem ? no - rem + mult : no);
  108. }
  109. static inline unsigned int
  110. ceil_quot(unsigned int d1, unsigned int d2)
  111. {
  112. return (d1 + (d2 - 1)) / d2;
  113. }
  114. static inline int
  115. bytes_per_record(struct dasd_eckd_characteristics *rdc, int kl, int dl)
  116. {
  117. unsigned int fl1, fl2, int1, int2;
  118. int bpr;
  119. switch (rdc->formula) {
  120. case 0x01:
  121. fl1 = round_up_multiple(ECKD_F2(rdc) + dl, ECKD_F1(rdc));
  122. fl2 = round_up_multiple(kl ? ECKD_F2(rdc) + kl : 0,
  123. ECKD_F1(rdc));
  124. bpr = fl1 + fl2;
  125. break;
  126. case 0x02:
  127. int1 = ceil_quot(dl + ECKD_F6(rdc), ECKD_F5(rdc) << 1);
  128. int2 = ceil_quot(kl + ECKD_F6(rdc), ECKD_F5(rdc) << 1);
  129. fl1 = round_up_multiple(ECKD_F1(rdc) * ECKD_F2(rdc) + dl +
  130. ECKD_F6(rdc) + ECKD_F4(rdc) * int1,
  131. ECKD_F1(rdc));
  132. fl2 = round_up_multiple(ECKD_F1(rdc) * ECKD_F3(rdc) + kl +
  133. ECKD_F6(rdc) + ECKD_F4(rdc) * int2,
  134. ECKD_F1(rdc));
  135. bpr = fl1 + fl2;
  136. break;
  137. default:
  138. bpr = 0;
  139. break;
  140. }
  141. return bpr;
  142. }
  143. static inline unsigned int
  144. bytes_per_track(struct dasd_eckd_characteristics *rdc)
  145. {
  146. return *(unsigned int *) (rdc->byte_per_track) >> 8;
  147. }
  148. static inline unsigned int
  149. recs_per_track(struct dasd_eckd_characteristics * rdc,
  150. unsigned int kl, unsigned int dl)
  151. {
  152. int dn, kn;
  153. switch (rdc->dev_type) {
  154. case 0x3380:
  155. if (kl)
  156. return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) +
  157. ceil_quot(dl + 12, 32));
  158. else
  159. return 1499 / (15 + ceil_quot(dl + 12, 32));
  160. case 0x3390:
  161. dn = ceil_quot(dl + 6, 232) + 1;
  162. if (kl) {
  163. kn = ceil_quot(kl + 6, 232) + 1;
  164. return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
  165. 9 + ceil_quot(dl + 6 * dn, 34));
  166. } else
  167. return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
  168. case 0x9345:
  169. dn = ceil_quot(dl + 6, 232) + 1;
  170. if (kl) {
  171. kn = ceil_quot(kl + 6, 232) + 1;
  172. return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) +
  173. ceil_quot(dl + 6 * dn, 34));
  174. } else
  175. return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34));
  176. }
  177. return 0;
  178. }
  179. static inline void
  180. check_XRC (struct ccw1 *de_ccw,
  181. struct DE_eckd_data *data,
  182. struct dasd_device *device)
  183. {
  184. struct dasd_eckd_private *private;
  185. private = (struct dasd_eckd_private *) device->private;
  186. /* switch on System Time Stamp - needed for XRC Support */
  187. if (private->rdc_data.facilities.XRC_supported) {
  188. data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
  189. data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
  190. data->ep_sys_time = get_clock ();
  191. de_ccw->count = sizeof (struct DE_eckd_data);
  192. de_ccw->flags |= CCW_FLAG_SLI;
  193. }
  194. return;
  195. } /* end check_XRC */
  196. static inline void
  197. define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
  198. int totrk, int cmd, struct dasd_device * device)
  199. {
  200. struct dasd_eckd_private *private;
  201. struct ch_t geo, beg, end;
  202. private = (struct dasd_eckd_private *) device->private;
  203. ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
  204. ccw->flags = 0;
  205. ccw->count = 16;
  206. ccw->cda = (__u32) __pa(data);
  207. memset(data, 0, sizeof (struct DE_eckd_data));
  208. switch (cmd) {
  209. case DASD_ECKD_CCW_READ_HOME_ADDRESS:
  210. case DASD_ECKD_CCW_READ_RECORD_ZERO:
  211. case DASD_ECKD_CCW_READ:
  212. case DASD_ECKD_CCW_READ_MT:
  213. case DASD_ECKD_CCW_READ_CKD:
  214. case DASD_ECKD_CCW_READ_CKD_MT:
  215. case DASD_ECKD_CCW_READ_KD:
  216. case DASD_ECKD_CCW_READ_KD_MT:
  217. case DASD_ECKD_CCW_READ_COUNT:
  218. data->mask.perm = 0x1;
  219. data->attributes.operation = private->attrib.operation;
  220. break;
  221. case DASD_ECKD_CCW_WRITE:
  222. case DASD_ECKD_CCW_WRITE_MT:
  223. case DASD_ECKD_CCW_WRITE_KD:
  224. case DASD_ECKD_CCW_WRITE_KD_MT:
  225. data->mask.perm = 0x02;
  226. data->attributes.operation = private->attrib.operation;
  227. check_XRC (ccw, data, device);
  228. break;
  229. case DASD_ECKD_CCW_WRITE_CKD:
  230. case DASD_ECKD_CCW_WRITE_CKD_MT:
  231. data->attributes.operation = DASD_BYPASS_CACHE;
  232. check_XRC (ccw, data, device);
  233. break;
  234. case DASD_ECKD_CCW_ERASE:
  235. case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
  236. case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
  237. data->mask.perm = 0x3;
  238. data->mask.auth = 0x1;
  239. data->attributes.operation = DASD_BYPASS_CACHE;
  240. check_XRC (ccw, data, device);
  241. break;
  242. default:
  243. DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
  244. break;
  245. }
  246. data->attributes.mode = 0x3; /* ECKD */
  247. if ((private->rdc_data.cu_type == 0x2105 ||
  248. private->rdc_data.cu_type == 0x2107 ||
  249. private->rdc_data.cu_type == 0x1750)
  250. && !(private->uses_cdl && trk < 2))
  251. data->ga_extended |= 0x40; /* Regular Data Format Mode */
  252. geo.cyl = private->rdc_data.no_cyl;
  253. geo.head = private->rdc_data.trk_per_cyl;
  254. beg.cyl = trk / geo.head;
  255. beg.head = trk % geo.head;
  256. end.cyl = totrk / geo.head;
  257. end.head = totrk % geo.head;
  258. /* check for sequential prestage - enhance cylinder range */
  259. if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
  260. data->attributes.operation == DASD_SEQ_ACCESS) {
  261. if (end.cyl + private->attrib.nr_cyl < geo.cyl)
  262. end.cyl += private->attrib.nr_cyl;
  263. else
  264. end.cyl = (geo.cyl - 1);
  265. }
  266. data->beg_ext.cyl = beg.cyl;
  267. data->beg_ext.head = beg.head;
  268. data->end_ext.cyl = end.cyl;
  269. data->end_ext.head = end.head;
  270. }
  271. static inline void
  272. locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
  273. int rec_on_trk, int no_rec, int cmd,
  274. struct dasd_device * device, int reclen)
  275. {
  276. struct dasd_eckd_private *private;
  277. int sector;
  278. int dn, d;
  279. private = (struct dasd_eckd_private *) device->private;
  280. DBF_DEV_EVENT(DBF_INFO, device,
  281. "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",
  282. trk, rec_on_trk, no_rec, cmd, reclen);
  283. ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
  284. ccw->flags = 0;
  285. ccw->count = 16;
  286. ccw->cda = (__u32) __pa(data);
  287. memset(data, 0, sizeof (struct LO_eckd_data));
  288. sector = 0;
  289. if (rec_on_trk) {
  290. switch (private->rdc_data.dev_type) {
  291. case 0x3390:
  292. dn = ceil_quot(reclen + 6, 232);
  293. d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
  294. sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
  295. break;
  296. case 0x3380:
  297. d = 7 + ceil_quot(reclen + 12, 32);
  298. sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
  299. break;
  300. }
  301. }
  302. data->sector = sector;
  303. data->count = no_rec;
  304. switch (cmd) {
  305. case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
  306. data->operation.orientation = 0x3;
  307. data->operation.operation = 0x03;
  308. break;
  309. case DASD_ECKD_CCW_READ_HOME_ADDRESS:
  310. data->operation.orientation = 0x3;
  311. data->operation.operation = 0x16;
  312. break;
  313. case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
  314. data->operation.orientation = 0x1;
  315. data->operation.operation = 0x03;
  316. data->count++;
  317. break;
  318. case DASD_ECKD_CCW_READ_RECORD_ZERO:
  319. data->operation.orientation = 0x3;
  320. data->operation.operation = 0x16;
  321. data->count++;
  322. break;
  323. case DASD_ECKD_CCW_WRITE:
  324. case DASD_ECKD_CCW_WRITE_MT:
  325. case DASD_ECKD_CCW_WRITE_KD:
  326. case DASD_ECKD_CCW_WRITE_KD_MT:
  327. data->auxiliary.last_bytes_used = 0x1;
  328. data->length = reclen;
  329. data->operation.operation = 0x01;
  330. break;
  331. case DASD_ECKD_CCW_WRITE_CKD:
  332. case DASD_ECKD_CCW_WRITE_CKD_MT:
  333. data->auxiliary.last_bytes_used = 0x1;
  334. data->length = reclen;
  335. data->operation.operation = 0x03;
  336. break;
  337. case DASD_ECKD_CCW_READ:
  338. case DASD_ECKD_CCW_READ_MT:
  339. case DASD_ECKD_CCW_READ_KD:
  340. case DASD_ECKD_CCW_READ_KD_MT:
  341. data->auxiliary.last_bytes_used = 0x1;
  342. data->length = reclen;
  343. data->operation.operation = 0x06;
  344. break;
  345. case DASD_ECKD_CCW_READ_CKD:
  346. case DASD_ECKD_CCW_READ_CKD_MT:
  347. data->auxiliary.last_bytes_used = 0x1;
  348. data->length = reclen;
  349. data->operation.operation = 0x16;
  350. break;
  351. case DASD_ECKD_CCW_READ_COUNT:
  352. data->operation.operation = 0x06;
  353. break;
  354. case DASD_ECKD_CCW_ERASE:
  355. data->length = reclen;
  356. data->auxiliary.last_bytes_used = 0x1;
  357. data->operation.operation = 0x0b;
  358. break;
  359. default:
  360. DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
  361. }
  362. data->seek_addr.cyl = data->search_arg.cyl =
  363. trk / private->rdc_data.trk_per_cyl;
  364. data->seek_addr.head = data->search_arg.head =
  365. trk % private->rdc_data.trk_per_cyl;
  366. data->search_arg.record = rec_on_trk;
  367. }
  368. /*
  369. * Returns 1 if the block is one of the special blocks that needs
  370. * to get read/written with the KD variant of the command.
  371. * That is DASD_ECKD_READ_KD_MT instead of DASD_ECKD_READ_MT and
  372. * DASD_ECKD_WRITE_KD_MT instead of DASD_ECKD_WRITE_MT.
  373. * Luckily the KD variants differ only by one bit (0x08) from the
  374. * normal variant. So don't wonder about code like:
  375. * if (dasd_eckd_cdl_special(blk_per_trk, recid))
  376. * ccw->cmd_code |= 0x8;
  377. */
  378. static inline int
  379. dasd_eckd_cdl_special(int blk_per_trk, int recid)
  380. {
  381. if (recid < 3)
  382. return 1;
  383. if (recid < blk_per_trk)
  384. return 0;
  385. if (recid < 2 * blk_per_trk)
  386. return 1;
  387. return 0;
  388. }
  389. /*
  390. * Returns the record size for the special blocks of the cdl format.
  391. * Only returns something useful if dasd_eckd_cdl_special is true
  392. * for the recid.
  393. */
  394. static inline int
  395. dasd_eckd_cdl_reclen(int recid)
  396. {
  397. if (recid < 3)
  398. return sizes_trk0[recid];
  399. return LABEL_SIZE;
  400. }
  401. static int
  402. dasd_eckd_read_conf(struct dasd_device *device)
  403. {
  404. void *conf_data;
  405. int conf_len, conf_data_saved;
  406. int rc;
  407. __u8 lpm;
  408. struct dasd_eckd_private *private;
  409. struct dasd_eckd_path *path_data;
  410. private = (struct dasd_eckd_private *) device->private;
  411. path_data = (struct dasd_eckd_path *) &private->path_data;
  412. path_data->opm = ccw_device_get_path_mask(device->cdev);
  413. lpm = 0x80;
  414. conf_data_saved = 0;
  415. /* get configuration data per operational path */
  416. for (lpm = 0x80; lpm; lpm>>= 1) {
  417. if (lpm & path_data->opm){
  418. rc = read_conf_data_lpm(device->cdev, &conf_data,
  419. &conf_len, lpm);
  420. if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
  421. MESSAGE(KERN_WARNING,
  422. "Read configuration data returned "
  423. "error %d", rc);
  424. return rc;
  425. }
  426. if (conf_data == NULL) {
  427. MESSAGE(KERN_WARNING, "%s", "No configuration "
  428. "data retrieved");
  429. continue; /* no errror */
  430. }
  431. if (conf_len != sizeof (struct dasd_eckd_confdata)) {
  432. MESSAGE(KERN_WARNING,
  433. "sizes of configuration data mismatch"
  434. "%d (read) vs %ld (expected)",
  435. conf_len,
  436. sizeof (struct dasd_eckd_confdata));
  437. kfree(conf_data);
  438. continue; /* no errror */
  439. }
  440. /* save first valid configuration data */
  441. if (!conf_data_saved){
  442. memcpy(&private->conf_data, conf_data,
  443. sizeof (struct dasd_eckd_confdata));
  444. conf_data_saved++;
  445. }
  446. switch (((char *)conf_data)[242] & 0x07){
  447. case 0x02:
  448. path_data->npm |= lpm;
  449. break;
  450. case 0x03:
  451. path_data->ppm |= lpm;
  452. break;
  453. }
  454. kfree(conf_data);
  455. }
  456. }
  457. return 0;
  458. }
  459. static int
  460. dasd_eckd_check_characteristics(struct dasd_device *device)
  461. {
  462. struct dasd_eckd_private *private;
  463. void *rdc_data;
  464. int rc;
  465. private = (struct dasd_eckd_private *) device->private;
  466. if (private == NULL) {
  467. private = kmalloc(sizeof(struct dasd_eckd_private),
  468. GFP_KERNEL | GFP_DMA);
  469. if (private == NULL) {
  470. DEV_MESSAGE(KERN_WARNING, device, "%s",
  471. "memory allocation failed for private "
  472. "data");
  473. return -ENOMEM;
  474. }
  475. memset(private, 0, sizeof(struct dasd_eckd_private));
  476. device->private = (void *) private;
  477. }
  478. /* Invalidate status of initial analysis. */
  479. private->init_cqr_status = -1;
  480. /* Set default cache operations. */
  481. private->attrib.operation = DASD_NORMAL_CACHE;
  482. private->attrib.nr_cyl = 0;
  483. /* Read Device Characteristics */
  484. rdc_data = (void *) &(private->rdc_data);
  485. rc = read_dev_chars(device->cdev, &rdc_data, 64);
  486. if (rc) {
  487. DEV_MESSAGE(KERN_WARNING, device,
  488. "Read device characteristics returned error %d",
  489. rc);
  490. return rc;
  491. }
  492. DEV_MESSAGE(KERN_INFO, device,
  493. "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
  494. private->rdc_data.dev_type,
  495. private->rdc_data.dev_model,
  496. private->rdc_data.cu_type,
  497. private->rdc_data.cu_model.model,
  498. private->rdc_data.no_cyl,
  499. private->rdc_data.trk_per_cyl,
  500. private->rdc_data.sec_per_trk);
  501. /* Read Configuration Data */
  502. rc = dasd_eckd_read_conf (device);
  503. return rc;
  504. }
  505. static struct dasd_ccw_req *
  506. dasd_eckd_analysis_ccw(struct dasd_device *device)
  507. {
  508. struct dasd_eckd_private *private;
  509. struct eckd_count *count_data;
  510. struct LO_eckd_data *LO_data;
  511. struct dasd_ccw_req *cqr;
  512. struct ccw1 *ccw;
  513. int cplength, datasize;
  514. int i;
  515. private = (struct dasd_eckd_private *) device->private;
  516. cplength = 8;
  517. datasize = sizeof(struct DE_eckd_data) + 2*sizeof(struct LO_eckd_data);
  518. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  519. cplength, datasize, device);
  520. if (IS_ERR(cqr))
  521. return cqr;
  522. ccw = cqr->cpaddr;
  523. /* Define extent for the first 3 tracks. */
  524. define_extent(ccw++, cqr->data, 0, 2,
  525. DASD_ECKD_CCW_READ_COUNT, device);
  526. LO_data = cqr->data + sizeof (struct DE_eckd_data);
  527. /* Locate record for the first 4 records on track 0. */
  528. ccw[-1].flags |= CCW_FLAG_CC;
  529. locate_record(ccw++, LO_data++, 0, 0, 4,
  530. DASD_ECKD_CCW_READ_COUNT, device, 0);
  531. count_data = private->count_area;
  532. for (i = 0; i < 4; i++) {
  533. ccw[-1].flags |= CCW_FLAG_CC;
  534. ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
  535. ccw->flags = 0;
  536. ccw->count = 8;
  537. ccw->cda = (__u32)(addr_t) count_data;
  538. ccw++;
  539. count_data++;
  540. }
  541. /* Locate record for the first record on track 2. */
  542. ccw[-1].flags |= CCW_FLAG_CC;
  543. locate_record(ccw++, LO_data++, 2, 0, 1,
  544. DASD_ECKD_CCW_READ_COUNT, device, 0);
  545. /* Read count ccw. */
  546. ccw[-1].flags |= CCW_FLAG_CC;
  547. ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
  548. ccw->flags = 0;
  549. ccw->count = 8;
  550. ccw->cda = (__u32)(addr_t) count_data;
  551. cqr->device = device;
  552. cqr->retries = 0;
  553. cqr->buildclk = get_clock();
  554. cqr->status = DASD_CQR_FILLED;
  555. return cqr;
  556. }
  557. /*
  558. * This is the callback function for the init_analysis cqr. It saves
  559. * the status of the initial analysis ccw before it frees it and kicks
  560. * the device to continue the startup sequence. This will call
  561. * dasd_eckd_do_analysis again (if the devices has not been marked
  562. * for deletion in the meantime).
  563. */
  564. static void
  565. dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data)
  566. {
  567. struct dasd_eckd_private *private;
  568. struct dasd_device *device;
  569. device = init_cqr->device;
  570. private = (struct dasd_eckd_private *) device->private;
  571. private->init_cqr_status = init_cqr->status;
  572. dasd_sfree_request(init_cqr, device);
  573. dasd_kick_device(device);
  574. }
  575. static int
  576. dasd_eckd_start_analysis(struct dasd_device *device)
  577. {
  578. struct dasd_eckd_private *private;
  579. struct dasd_ccw_req *init_cqr;
  580. private = (struct dasd_eckd_private *) device->private;
  581. init_cqr = dasd_eckd_analysis_ccw(device);
  582. if (IS_ERR(init_cqr))
  583. return PTR_ERR(init_cqr);
  584. init_cqr->callback = dasd_eckd_analysis_callback;
  585. init_cqr->callback_data = NULL;
  586. init_cqr->expires = 5*HZ;
  587. dasd_add_request_head(init_cqr);
  588. return -EAGAIN;
  589. }
  590. static int
  591. dasd_eckd_end_analysis(struct dasd_device *device)
  592. {
  593. struct dasd_eckd_private *private;
  594. struct eckd_count *count_area;
  595. unsigned int sb, blk_per_trk;
  596. int status, i;
  597. private = (struct dasd_eckd_private *) device->private;
  598. status = private->init_cqr_status;
  599. private->init_cqr_status = -1;
  600. if (status != DASD_CQR_DONE) {
  601. DEV_MESSAGE(KERN_WARNING, device, "%s",
  602. "volume analysis returned unformatted disk");
  603. return -EMEDIUMTYPE;
  604. }
  605. private->uses_cdl = 1;
  606. /* Calculate number of blocks/records per track. */
  607. blk_per_trk = recs_per_track(&private->rdc_data, 0, device->bp_block);
  608. /* Check Track 0 for Compatible Disk Layout */
  609. count_area = NULL;
  610. for (i = 0; i < 3; i++) {
  611. if (private->count_area[i].kl != 4 ||
  612. private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4) {
  613. private->uses_cdl = 0;
  614. break;
  615. }
  616. }
  617. if (i == 3)
  618. count_area = &private->count_area[4];
  619. if (private->uses_cdl == 0) {
  620. for (i = 0; i < 5; i++) {
  621. if ((private->count_area[i].kl != 0) ||
  622. (private->count_area[i].dl !=
  623. private->count_area[0].dl))
  624. break;
  625. }
  626. if (i == 5)
  627. count_area = &private->count_area[0];
  628. } else {
  629. if (private->count_area[3].record == 1)
  630. DEV_MESSAGE(KERN_WARNING, device, "%s",
  631. "Trk 0: no records after VTOC!");
  632. }
  633. if (count_area != NULL && count_area->kl == 0) {
  634. /* we found notthing violating our disk layout */
  635. if (dasd_check_blocksize(count_area->dl) == 0)
  636. device->bp_block = count_area->dl;
  637. }
  638. if (device->bp_block == 0) {
  639. DEV_MESSAGE(KERN_WARNING, device, "%s",
  640. "Volume has incompatible disk layout");
  641. return -EMEDIUMTYPE;
  642. }
  643. device->s2b_shift = 0; /* bits to shift 512 to get a block */
  644. for (sb = 512; sb < device->bp_block; sb = sb << 1)
  645. device->s2b_shift++;
  646. blk_per_trk = recs_per_track(&private->rdc_data, 0, device->bp_block);
  647. device->blocks = (private->rdc_data.no_cyl *
  648. private->rdc_data.trk_per_cyl *
  649. blk_per_trk);
  650. DEV_MESSAGE(KERN_INFO, device,
  651. "(%dkB blks): %dkB at %dkB/trk %s",
  652. (device->bp_block >> 10),
  653. ((private->rdc_data.no_cyl *
  654. private->rdc_data.trk_per_cyl *
  655. blk_per_trk * (device->bp_block >> 9)) >> 1),
  656. ((blk_per_trk * device->bp_block) >> 10),
  657. private->uses_cdl ?
  658. "compatible disk layout" : "linux disk layout");
  659. return 0;
  660. }
  661. static int
  662. dasd_eckd_do_analysis(struct dasd_device *device)
  663. {
  664. struct dasd_eckd_private *private;
  665. private = (struct dasd_eckd_private *) device->private;
  666. if (private->init_cqr_status < 0)
  667. return dasd_eckd_start_analysis(device);
  668. else
  669. return dasd_eckd_end_analysis(device);
  670. }
  671. static int
  672. dasd_eckd_fill_geometry(struct dasd_device *device, struct hd_geometry *geo)
  673. {
  674. struct dasd_eckd_private *private;
  675. private = (struct dasd_eckd_private *) device->private;
  676. if (dasd_check_blocksize(device->bp_block) == 0) {
  677. geo->sectors = recs_per_track(&private->rdc_data,
  678. 0, device->bp_block);
  679. }
  680. geo->cylinders = private->rdc_data.no_cyl;
  681. geo->heads = private->rdc_data.trk_per_cyl;
  682. return 0;
  683. }
  684. static struct dasd_ccw_req *
  685. dasd_eckd_format_device(struct dasd_device * device,
  686. struct format_data_t * fdata)
  687. {
  688. struct dasd_eckd_private *private;
  689. struct dasd_ccw_req *fcp;
  690. struct eckd_count *ect;
  691. struct ccw1 *ccw;
  692. void *data;
  693. int rpt, cyl, head;
  694. int cplength, datasize;
  695. int i;
  696. private = (struct dasd_eckd_private *) device->private;
  697. rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
  698. cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
  699. head = fdata->start_unit % private->rdc_data.trk_per_cyl;
  700. /* Sanity checks. */
  701. if (fdata->start_unit >=
  702. (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
  703. DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
  704. fdata->start_unit);
  705. return ERR_PTR(-EINVAL);
  706. }
  707. if (fdata->start_unit > fdata->stop_unit) {
  708. DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
  709. fdata->start_unit);
  710. return ERR_PTR(-EINVAL);
  711. }
  712. if (dasd_check_blocksize(fdata->blksize) != 0) {
  713. DEV_MESSAGE(KERN_WARNING, device,
  714. "Invalid blocksize %d...terminating!",
  715. fdata->blksize);
  716. return ERR_PTR(-EINVAL);
  717. }
  718. /*
  719. * fdata->intensity is a bit string that tells us what to do:
  720. * Bit 0: write record zero
  721. * Bit 1: write home address, currently not supported
  722. * Bit 2: invalidate tracks
  723. * Bit 3: use OS/390 compatible disk layout (cdl)
  724. * Only some bit combinations do make sense.
  725. */
  726. switch (fdata->intensity) {
  727. case 0x00: /* Normal format */
  728. case 0x08: /* Normal format, use cdl. */
  729. cplength = 2 + rpt;
  730. datasize = sizeof(struct DE_eckd_data) +
  731. sizeof(struct LO_eckd_data) +
  732. rpt * sizeof(struct eckd_count);
  733. break;
  734. case 0x01: /* Write record zero and format track. */
  735. case 0x09: /* Write record zero and format track, use cdl. */
  736. cplength = 3 + rpt;
  737. datasize = sizeof(struct DE_eckd_data) +
  738. sizeof(struct LO_eckd_data) +
  739. sizeof(struct eckd_count) +
  740. rpt * sizeof(struct eckd_count);
  741. break;
  742. case 0x04: /* Invalidate track. */
  743. case 0x0c: /* Invalidate track, use cdl. */
  744. cplength = 3;
  745. datasize = sizeof(struct DE_eckd_data) +
  746. sizeof(struct LO_eckd_data) +
  747. sizeof(struct eckd_count);
  748. break;
  749. default:
  750. DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
  751. fdata->intensity);
  752. return ERR_PTR(-EINVAL);
  753. }
  754. /* Allocate the format ccw request. */
  755. fcp = dasd_smalloc_request(dasd_eckd_discipline.name,
  756. cplength, datasize, device);
  757. if (IS_ERR(fcp))
  758. return fcp;
  759. data = fcp->data;
  760. ccw = fcp->cpaddr;
  761. switch (fdata->intensity & ~0x08) {
  762. case 0x00: /* Normal format. */
  763. define_extent(ccw++, (struct DE_eckd_data *) data,
  764. fdata->start_unit, fdata->start_unit,
  765. DASD_ECKD_CCW_WRITE_CKD, device);
  766. data += sizeof(struct DE_eckd_data);
  767. ccw[-1].flags |= CCW_FLAG_CC;
  768. locate_record(ccw++, (struct LO_eckd_data *) data,
  769. fdata->start_unit, 0, rpt,
  770. DASD_ECKD_CCW_WRITE_CKD, device,
  771. fdata->blksize);
  772. data += sizeof(struct LO_eckd_data);
  773. break;
  774. case 0x01: /* Write record zero + format track. */
  775. define_extent(ccw++, (struct DE_eckd_data *) data,
  776. fdata->start_unit, fdata->start_unit,
  777. DASD_ECKD_CCW_WRITE_RECORD_ZERO,
  778. device);
  779. data += sizeof(struct DE_eckd_data);
  780. ccw[-1].flags |= CCW_FLAG_CC;
  781. locate_record(ccw++, (struct LO_eckd_data *) data,
  782. fdata->start_unit, 0, rpt + 1,
  783. DASD_ECKD_CCW_WRITE_RECORD_ZERO, device,
  784. device->bp_block);
  785. data += sizeof(struct LO_eckd_data);
  786. break;
  787. case 0x04: /* Invalidate track. */
  788. define_extent(ccw++, (struct DE_eckd_data *) data,
  789. fdata->start_unit, fdata->start_unit,
  790. DASD_ECKD_CCW_WRITE_CKD, device);
  791. data += sizeof(struct DE_eckd_data);
  792. ccw[-1].flags |= CCW_FLAG_CC;
  793. locate_record(ccw++, (struct LO_eckd_data *) data,
  794. fdata->start_unit, 0, 1,
  795. DASD_ECKD_CCW_WRITE_CKD, device, 8);
  796. data += sizeof(struct LO_eckd_data);
  797. break;
  798. }
  799. if (fdata->intensity & 0x01) { /* write record zero */
  800. ect = (struct eckd_count *) data;
  801. data += sizeof(struct eckd_count);
  802. ect->cyl = cyl;
  803. ect->head = head;
  804. ect->record = 0;
  805. ect->kl = 0;
  806. ect->dl = 8;
  807. ccw[-1].flags |= CCW_FLAG_CC;
  808. ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO;
  809. ccw->flags = CCW_FLAG_SLI;
  810. ccw->count = 8;
  811. ccw->cda = (__u32)(addr_t) ect;
  812. ccw++;
  813. }
  814. if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */
  815. ect = (struct eckd_count *) data;
  816. data += sizeof(struct eckd_count);
  817. ect->cyl = cyl;
  818. ect->head = head;
  819. ect->record = 1;
  820. ect->kl = 0;
  821. ect->dl = 0;
  822. ccw[-1].flags |= CCW_FLAG_CC;
  823. ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;
  824. ccw->flags = CCW_FLAG_SLI;
  825. ccw->count = 8;
  826. ccw->cda = (__u32)(addr_t) ect;
  827. } else { /* write remaining records */
  828. for (i = 0; i < rpt; i++) {
  829. ect = (struct eckd_count *) data;
  830. data += sizeof(struct eckd_count);
  831. ect->cyl = cyl;
  832. ect->head = head;
  833. ect->record = i + 1;
  834. ect->kl = 0;
  835. ect->dl = fdata->blksize;
  836. /* Check for special tracks 0-1 when formatting CDL */
  837. if ((fdata->intensity & 0x08) &&
  838. fdata->start_unit == 0) {
  839. if (i < 3) {
  840. ect->kl = 4;
  841. ect->dl = sizes_trk0[i] - 4;
  842. }
  843. }
  844. if ((fdata->intensity & 0x08) &&
  845. fdata->start_unit == 1) {
  846. ect->kl = 44;
  847. ect->dl = LABEL_SIZE - 44;
  848. }
  849. ccw[-1].flags |= CCW_FLAG_CC;
  850. ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;
  851. ccw->flags = CCW_FLAG_SLI;
  852. ccw->count = 8;
  853. ccw->cda = (__u32)(addr_t) ect;
  854. ccw++;
  855. }
  856. }
  857. fcp->device = device;
  858. fcp->retries = 2; /* set retry counter to enable ERP */
  859. fcp->buildclk = get_clock();
  860. fcp->status = DASD_CQR_FILLED;
  861. return fcp;
  862. }
  863. static dasd_era_t
  864. dasd_eckd_examine_error(struct dasd_ccw_req * cqr, struct irb * irb)
  865. {
  866. struct dasd_device *device = (struct dasd_device *) cqr->device;
  867. struct ccw_device *cdev = device->cdev;
  868. if (irb->scsw.cstat == 0x00 &&
  869. irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
  870. return dasd_era_none;
  871. switch (cdev->id.cu_type) {
  872. case 0x3990:
  873. case 0x2105:
  874. case 0x2107:
  875. case 0x1750:
  876. return dasd_3990_erp_examine(cqr, irb);
  877. case 0x9343:
  878. return dasd_9343_erp_examine(cqr, irb);
  879. case 0x3880:
  880. default:
  881. DEV_MESSAGE(KERN_WARNING, device, "%s",
  882. "default (unknown CU type) - RECOVERABLE return");
  883. return dasd_era_recover;
  884. }
  885. }
  886. static dasd_erp_fn_t
  887. dasd_eckd_erp_action(struct dasd_ccw_req * cqr)
  888. {
  889. struct dasd_device *device = (struct dasd_device *) cqr->device;
  890. struct ccw_device *cdev = device->cdev;
  891. switch (cdev->id.cu_type) {
  892. case 0x3990:
  893. case 0x2105:
  894. case 0x2107:
  895. case 0x1750:
  896. return dasd_3990_erp_action;
  897. case 0x9343:
  898. case 0x3880:
  899. default:
  900. return dasd_default_erp_action;
  901. }
  902. }
  903. static dasd_erp_fn_t
  904. dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr)
  905. {
  906. return dasd_default_erp_postaction;
  907. }
  908. static struct dasd_ccw_req *
  909. dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
  910. {
  911. struct dasd_eckd_private *private;
  912. unsigned long *idaws;
  913. struct LO_eckd_data *LO_data;
  914. struct dasd_ccw_req *cqr;
  915. struct ccw1 *ccw;
  916. struct bio *bio;
  917. struct bio_vec *bv;
  918. char *dst;
  919. unsigned int blksize, blk_per_trk, off;
  920. int count, cidaw, cplength, datasize;
  921. sector_t recid, first_rec, last_rec;
  922. sector_t first_trk, last_trk;
  923. unsigned int first_offs, last_offs;
  924. unsigned char cmd, rcmd;
  925. int i;
  926. private = (struct dasd_eckd_private *) device->private;
  927. if (rq_data_dir(req) == READ)
  928. cmd = DASD_ECKD_CCW_READ_MT;
  929. else if (rq_data_dir(req) == WRITE)
  930. cmd = DASD_ECKD_CCW_WRITE_MT;
  931. else
  932. return ERR_PTR(-EINVAL);
  933. /* Calculate number of blocks/records per track. */
  934. blksize = device->bp_block;
  935. blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
  936. /* Calculate record id of first and last block. */
  937. first_rec = first_trk = req->sector >> device->s2b_shift;
  938. first_offs = sector_div(first_trk, blk_per_trk);
  939. last_rec = last_trk =
  940. (req->sector + req->nr_sectors - 1) >> device->s2b_shift;
  941. last_offs = sector_div(last_trk, blk_per_trk);
  942. /* Check struct bio and count the number of blocks for the request. */
  943. count = 0;
  944. cidaw = 0;
  945. rq_for_each_bio(bio, req) {
  946. bio_for_each_segment(bv, bio, i) {
  947. if (bv->bv_len & (blksize - 1))
  948. /* Eckd can only do full blocks. */
  949. return ERR_PTR(-EINVAL);
  950. count += bv->bv_len >> (device->s2b_shift + 9);
  951. #if defined(CONFIG_ARCH_S390X)
  952. if (idal_is_needed (page_address(bv->bv_page),
  953. bv->bv_len))
  954. cidaw += bv->bv_len >> (device->s2b_shift + 9);
  955. #endif
  956. }
  957. }
  958. /* Paranoia. */
  959. if (count != last_rec - first_rec + 1)
  960. return ERR_PTR(-EINVAL);
  961. /* 1x define extent + 1x locate record + number of blocks */
  962. cplength = 2 + count;
  963. /* 1x define extent + 1x locate record + cidaws*sizeof(long) */
  964. datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) +
  965. cidaw * sizeof(unsigned long);
  966. /* Find out the number of additional locate record ccws for cdl. */
  967. if (private->uses_cdl && first_rec < 2*blk_per_trk) {
  968. if (last_rec >= 2*blk_per_trk)
  969. count = 2*blk_per_trk - first_rec;
  970. cplength += count;
  971. datasize += count*sizeof(struct LO_eckd_data);
  972. }
  973. /* Allocate the ccw request. */
  974. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  975. cplength, datasize, device);
  976. if (IS_ERR(cqr))
  977. return cqr;
  978. ccw = cqr->cpaddr;
  979. /* First ccw is define extent. */
  980. define_extent(ccw++, cqr->data, first_trk, last_trk, cmd, device);
  981. /* Build locate_record+read/write/ccws. */
  982. idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data));
  983. LO_data = (struct LO_eckd_data *) (idaws + cidaw);
  984. recid = first_rec;
  985. if (private->uses_cdl == 0 || recid > 2*blk_per_trk) {
  986. /* Only standard blocks so there is just one locate record. */
  987. ccw[-1].flags |= CCW_FLAG_CC;
  988. locate_record(ccw++, LO_data++, first_trk, first_offs + 1,
  989. last_rec - recid + 1, cmd, device, blksize);
  990. }
  991. rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) {
  992. dst = page_address(bv->bv_page) + bv->bv_offset;
  993. if (dasd_page_cache) {
  994. char *copy = kmem_cache_alloc(dasd_page_cache,
  995. SLAB_DMA | __GFP_NOWARN);
  996. if (copy && rq_data_dir(req) == WRITE)
  997. memcpy(copy + bv->bv_offset, dst, bv->bv_len);
  998. if (copy)
  999. dst = copy + bv->bv_offset;
  1000. }
  1001. for (off = 0; off < bv->bv_len; off += blksize) {
  1002. sector_t trkid = recid;
  1003. unsigned int recoffs = sector_div(trkid, blk_per_trk);
  1004. rcmd = cmd;
  1005. count = blksize;
  1006. /* Locate record for cdl special block ? */
  1007. if (private->uses_cdl && recid < 2*blk_per_trk) {
  1008. if (dasd_eckd_cdl_special(blk_per_trk, recid)){
  1009. rcmd |= 0x8;
  1010. count = dasd_eckd_cdl_reclen(recid);
  1011. if (count < blksize &&
  1012. rq_data_dir(req) == READ)
  1013. memset(dst + count, 0xe5,
  1014. blksize - count);
  1015. }
  1016. ccw[-1].flags |= CCW_FLAG_CC;
  1017. locate_record(ccw++, LO_data++,
  1018. trkid, recoffs + 1,
  1019. 1, rcmd, device, count);
  1020. }
  1021. /* Locate record for standard blocks ? */
  1022. if (private->uses_cdl && recid == 2*blk_per_trk) {
  1023. ccw[-1].flags |= CCW_FLAG_CC;
  1024. locate_record(ccw++, LO_data++,
  1025. trkid, recoffs + 1,
  1026. last_rec - recid + 1,
  1027. cmd, device, count);
  1028. }
  1029. /* Read/write ccw. */
  1030. ccw[-1].flags |= CCW_FLAG_CC;
  1031. ccw->cmd_code = rcmd;
  1032. ccw->count = count;
  1033. if (idal_is_needed(dst, blksize)) {
  1034. ccw->cda = (__u32)(addr_t) idaws;
  1035. ccw->flags = CCW_FLAG_IDA;
  1036. idaws = idal_create_words(idaws, dst, blksize);
  1037. } else {
  1038. ccw->cda = (__u32)(addr_t) dst;
  1039. ccw->flags = 0;
  1040. }
  1041. ccw++;
  1042. dst += blksize;
  1043. recid++;
  1044. }
  1045. }
  1046. cqr->device = device;
  1047. cqr->expires = 5 * 60 * HZ; /* 5 minutes */
  1048. cqr->lpm = private->path_data.ppm;
  1049. cqr->retries = 256;
  1050. cqr->buildclk = get_clock();
  1051. cqr->status = DASD_CQR_FILLED;
  1052. return cqr;
  1053. }
  1054. static int
  1055. dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
  1056. {
  1057. struct dasd_eckd_private *private;
  1058. struct ccw1 *ccw;
  1059. struct bio *bio;
  1060. struct bio_vec *bv;
  1061. char *dst, *cda;
  1062. unsigned int blksize, blk_per_trk, off;
  1063. sector_t recid;
  1064. int i, status;
  1065. if (!dasd_page_cache)
  1066. goto out;
  1067. private = (struct dasd_eckd_private *) cqr->device->private;
  1068. blksize = cqr->device->bp_block;
  1069. blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
  1070. recid = req->sector >> cqr->device->s2b_shift;
  1071. ccw = cqr->cpaddr;
  1072. /* Skip over define extent & locate record. */
  1073. ccw++;
  1074. if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
  1075. ccw++;
  1076. rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) {
  1077. dst = page_address(bv->bv_page) + bv->bv_offset;
  1078. for (off = 0; off < bv->bv_len; off += blksize) {
  1079. /* Skip locate record. */
  1080. if (private->uses_cdl && recid <= 2*blk_per_trk)
  1081. ccw++;
  1082. if (dst) {
  1083. if (ccw->flags & CCW_FLAG_IDA)
  1084. cda = *((char **)((addr_t) ccw->cda));
  1085. else
  1086. cda = (char *)((addr_t) ccw->cda);
  1087. if (dst != cda) {
  1088. if (rq_data_dir(req) == READ)
  1089. memcpy(dst, cda, bv->bv_len);
  1090. kmem_cache_free(dasd_page_cache,
  1091. (void *)((addr_t)cda & PAGE_MASK));
  1092. }
  1093. dst = NULL;
  1094. }
  1095. ccw++;
  1096. recid++;
  1097. }
  1098. }
  1099. out:
  1100. status = cqr->status == DASD_CQR_DONE;
  1101. dasd_sfree_request(cqr, cqr->device);
  1102. return status;
  1103. }
  1104. static int
  1105. dasd_eckd_fill_info(struct dasd_device * device,
  1106. struct dasd_information2_t * info)
  1107. {
  1108. struct dasd_eckd_private *private;
  1109. private = (struct dasd_eckd_private *) device->private;
  1110. info->label_block = 2;
  1111. info->FBA_layout = private->uses_cdl ? 0 : 1;
  1112. info->format = private->uses_cdl ? DASD_FORMAT_CDL : DASD_FORMAT_LDL;
  1113. info->characteristics_size = sizeof(struct dasd_eckd_characteristics);
  1114. memcpy(info->characteristics, &private->rdc_data,
  1115. sizeof(struct dasd_eckd_characteristics));
  1116. info->confdata_size = sizeof (struct dasd_eckd_confdata);
  1117. memcpy(info->configuration_data, &private->conf_data,
  1118. sizeof (struct dasd_eckd_confdata));
  1119. return 0;
  1120. }
  1121. /*
  1122. * SECTION: ioctl functions for eckd devices.
  1123. */
  1124. /*
  1125. * Release device ioctl.
  1126. * Buils a channel programm to releases a prior reserved
  1127. * (see dasd_eckd_reserve) device.
  1128. */
  1129. static int
  1130. dasd_eckd_release(struct block_device *bdev, int no, long args)
  1131. {
  1132. struct dasd_device *device;
  1133. struct dasd_ccw_req *cqr;
  1134. int rc;
  1135. if (!capable(CAP_SYS_ADMIN))
  1136. return -EACCES;
  1137. device = bdev->bd_disk->private_data;
  1138. if (device == NULL)
  1139. return -ENODEV;
  1140. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1141. 1, 32, device);
  1142. if (IS_ERR(cqr)) {
  1143. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1144. "Could not allocate initialization request");
  1145. return PTR_ERR(cqr);
  1146. }
  1147. cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
  1148. cqr->cpaddr->flags |= CCW_FLAG_SLI;
  1149. cqr->cpaddr->count = 32;
  1150. cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
  1151. cqr->device = device;
  1152. clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
  1153. cqr->retries = 0;
  1154. cqr->expires = 2 * HZ;
  1155. cqr->buildclk = get_clock();
  1156. cqr->status = DASD_CQR_FILLED;
  1157. rc = dasd_sleep_on_immediatly(cqr);
  1158. dasd_sfree_request(cqr, cqr->device);
  1159. return rc;
  1160. }
  1161. /*
  1162. * Reserve device ioctl.
  1163. * Options are set to 'synchronous wait for interrupt' and
  1164. * 'timeout the request'. This leads to a terminate IO if
  1165. * the interrupt is outstanding for a certain time.
  1166. */
  1167. static int
  1168. dasd_eckd_reserve(struct block_device *bdev, int no, long args)
  1169. {
  1170. struct dasd_device *device;
  1171. struct dasd_ccw_req *cqr;
  1172. int rc;
  1173. if (!capable(CAP_SYS_ADMIN))
  1174. return -EACCES;
  1175. device = bdev->bd_disk->private_data;
  1176. if (device == NULL)
  1177. return -ENODEV;
  1178. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1179. 1, 32, device);
  1180. if (IS_ERR(cqr)) {
  1181. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1182. "Could not allocate initialization request");
  1183. return PTR_ERR(cqr);
  1184. }
  1185. cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
  1186. cqr->cpaddr->flags |= CCW_FLAG_SLI;
  1187. cqr->cpaddr->count = 32;
  1188. cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
  1189. cqr->device = device;
  1190. clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
  1191. cqr->retries = 0;
  1192. cqr->expires = 2 * HZ;
  1193. cqr->buildclk = get_clock();
  1194. cqr->status = DASD_CQR_FILLED;
  1195. rc = dasd_sleep_on_immediatly(cqr);
  1196. dasd_sfree_request(cqr, cqr->device);
  1197. return rc;
  1198. }
  1199. /*
  1200. * Steal lock ioctl - unconditional reserve device.
  1201. * Buils a channel programm to break a device's reservation.
  1202. * (unconditional reserve)
  1203. */
  1204. static int
  1205. dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
  1206. {
  1207. struct dasd_device *device;
  1208. struct dasd_ccw_req *cqr;
  1209. int rc;
  1210. if (!capable(CAP_SYS_ADMIN))
  1211. return -EACCES;
  1212. device = bdev->bd_disk->private_data;
  1213. if (device == NULL)
  1214. return -ENODEV;
  1215. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1216. 1, 32, device);
  1217. if (IS_ERR(cqr)) {
  1218. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1219. "Could not allocate initialization request");
  1220. return PTR_ERR(cqr);
  1221. }
  1222. cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
  1223. cqr->cpaddr->flags |= CCW_FLAG_SLI;
  1224. cqr->cpaddr->count = 32;
  1225. cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
  1226. cqr->device = device;
  1227. clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
  1228. cqr->retries = 0;
  1229. cqr->expires = 2 * HZ;
  1230. cqr->buildclk = get_clock();
  1231. cqr->status = DASD_CQR_FILLED;
  1232. rc = dasd_sleep_on_immediatly(cqr);
  1233. dasd_sfree_request(cqr, cqr->device);
  1234. return rc;
  1235. }
  1236. /*
  1237. * Read performance statistics
  1238. */
  1239. static int
  1240. dasd_eckd_performance(struct block_device *bdev, int no, long args)
  1241. {
  1242. struct dasd_device *device;
  1243. struct dasd_psf_prssd_data *prssdp;
  1244. struct dasd_rssd_perf_stats_t *stats;
  1245. struct dasd_ccw_req *cqr;
  1246. struct ccw1 *ccw;
  1247. int rc;
  1248. device = bdev->bd_disk->private_data;
  1249. if (device == NULL)
  1250. return -ENODEV;
  1251. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1252. 1 /* PSF */ + 1 /* RSSD */ ,
  1253. (sizeof (struct dasd_psf_prssd_data) +
  1254. sizeof (struct dasd_rssd_perf_stats_t)),
  1255. device);
  1256. if (IS_ERR(cqr)) {
  1257. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1258. "Could not allocate initialization request");
  1259. return PTR_ERR(cqr);
  1260. }
  1261. cqr->device = device;
  1262. cqr->retries = 0;
  1263. cqr->expires = 10 * HZ;
  1264. /* Prepare for Read Subsystem Data */
  1265. prssdp = (struct dasd_psf_prssd_data *) cqr->data;
  1266. memset(prssdp, 0, sizeof (struct dasd_psf_prssd_data));
  1267. prssdp->order = PSF_ORDER_PRSSD;
  1268. prssdp->suborder = 0x01; /* Perfomance Statistics */
  1269. prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */
  1270. ccw = cqr->cpaddr;
  1271. ccw->cmd_code = DASD_ECKD_CCW_PSF;
  1272. ccw->count = sizeof (struct dasd_psf_prssd_data);
  1273. ccw->flags |= CCW_FLAG_CC;
  1274. ccw->cda = (__u32)(addr_t) prssdp;
  1275. /* Read Subsystem Data - Performance Statistics */
  1276. stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
  1277. memset(stats, 0, sizeof (struct dasd_rssd_perf_stats_t));
  1278. ccw++;
  1279. ccw->cmd_code = DASD_ECKD_CCW_RSSD;
  1280. ccw->count = sizeof (struct dasd_rssd_perf_stats_t);
  1281. ccw->cda = (__u32)(addr_t) stats;
  1282. cqr->buildclk = get_clock();
  1283. cqr->status = DASD_CQR_FILLED;
  1284. rc = dasd_sleep_on(cqr);
  1285. if (rc == 0) {
  1286. /* Prepare for Read Subsystem Data */
  1287. prssdp = (struct dasd_psf_prssd_data *) cqr->data;
  1288. stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
  1289. rc = copy_to_user((long __user *) args, (long *) stats,
  1290. sizeof(struct dasd_rssd_perf_stats_t));
  1291. }
  1292. dasd_sfree_request(cqr, cqr->device);
  1293. return rc;
  1294. }
  1295. /*
  1296. * Get attributes (cache operations)
  1297. * Returnes the cache attributes used in Define Extend (DE).
  1298. */
  1299. static int
  1300. dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
  1301. {
  1302. struct dasd_device *device;
  1303. struct dasd_eckd_private *private;
  1304. struct attrib_data_t attrib;
  1305. int rc;
  1306. if (!capable(CAP_SYS_ADMIN))
  1307. return -EACCES;
  1308. if (!args)
  1309. return -EINVAL;
  1310. device = bdev->bd_disk->private_data;
  1311. if (device == NULL)
  1312. return -ENODEV;
  1313. private = (struct dasd_eckd_private *) device->private;
  1314. attrib = private->attrib;
  1315. rc = copy_to_user((long __user *) args, (long *) &attrib,
  1316. sizeof (struct attrib_data_t));
  1317. return rc;
  1318. }
  1319. /*
  1320. * Set attributes (cache operations)
  1321. * Stores the attributes for cache operation to be used in Define Extend (DE).
  1322. */
  1323. static int
  1324. dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
  1325. {
  1326. struct dasd_device *device;
  1327. struct dasd_eckd_private *private;
  1328. struct attrib_data_t attrib;
  1329. if (!capable(CAP_SYS_ADMIN))
  1330. return -EACCES;
  1331. if (!args)
  1332. return -EINVAL;
  1333. device = bdev->bd_disk->private_data;
  1334. if (device == NULL)
  1335. return -ENODEV;
  1336. if (copy_from_user(&attrib, (void __user *) args,
  1337. sizeof (struct attrib_data_t))) {
  1338. return -EFAULT;
  1339. }
  1340. private = (struct dasd_eckd_private *) device->private;
  1341. private->attrib = attrib;
  1342. DEV_MESSAGE(KERN_INFO, device,
  1343. "cache operation mode set to %x (%i cylinder prestage)",
  1344. private->attrib.operation, private->attrib.nr_cyl);
  1345. return 0;
  1346. }
  1347. /*
  1348. * Print sense data and related channel program.
  1349. * Parts are printed because printk buffer is only 1024 bytes.
  1350. */
  1351. static void
  1352. dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
  1353. struct irb *irb)
  1354. {
  1355. char *page;
  1356. struct ccw1 *act, *end, *last;
  1357. int len, sl, sct, count;
  1358. page = (char *) get_zeroed_page(GFP_ATOMIC);
  1359. if (page == NULL) {
  1360. DEV_MESSAGE(KERN_ERR, device, " %s",
  1361. "No memory to dump sense data");
  1362. return;
  1363. }
  1364. len = sprintf(page, KERN_ERR PRINTK_HEADER
  1365. " I/O status report for device %s:\n",
  1366. device->cdev->dev.bus_id);
  1367. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1368. " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
  1369. irb->scsw.cstat, irb->scsw.dstat);
  1370. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1371. " device %s: Failing CCW: %p\n",
  1372. device->cdev->dev.bus_id,
  1373. (void *) (addr_t) irb->scsw.cpa);
  1374. if (irb->esw.esw0.erw.cons) {
  1375. for (sl = 0; sl < 4; sl++) {
  1376. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1377. " Sense(hex) %2d-%2d:",
  1378. (8 * sl), ((8 * sl) + 7));
  1379. for (sct = 0; sct < 8; sct++) {
  1380. len += sprintf(page + len, " %02x",
  1381. irb->ecw[8 * sl + sct]);
  1382. }
  1383. len += sprintf(page + len, "\n");
  1384. }
  1385. if (irb->ecw[27] & DASD_SENSE_BIT_0) {
  1386. /* 24 Byte Sense Data */
  1387. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1388. " 24 Byte: %x MSG %x, "
  1389. "%s MSGb to SYSOP\n",
  1390. irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
  1391. irb->ecw[1] & 0x10 ? "" : "no");
  1392. } else {
  1393. /* 32 Byte Sense Data */
  1394. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1395. " 32 Byte: Format: %x "
  1396. "Exception class %x\n",
  1397. irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
  1398. }
  1399. } else {
  1400. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1401. " SORRY - NO VALID SENSE AVAILABLE\n");
  1402. }
  1403. MESSAGE_LOG(KERN_ERR, "%s",
  1404. page + sizeof(KERN_ERR PRINTK_HEADER));
  1405. /* dump the Channel Program */
  1406. /* print first CCWs (maximum 8) */
  1407. act = req->cpaddr;
  1408. for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
  1409. end = min(act + 8, last);
  1410. len = sprintf(page, KERN_ERR PRINTK_HEADER
  1411. " Related CP in req: %p\n", req);
  1412. while (act <= end) {
  1413. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1414. " CCW %p: %08X %08X DAT:",
  1415. act, ((int *) act)[0], ((int *) act)[1]);
  1416. for (count = 0; count < 32 && count < act->count;
  1417. count += sizeof(int))
  1418. len += sprintf(page + len, " %08X",
  1419. ((int *) (addr_t) act->cda)
  1420. [(count>>2)]);
  1421. len += sprintf(page + len, "\n");
  1422. act++;
  1423. }
  1424. MESSAGE_LOG(KERN_ERR, "%s",
  1425. page + sizeof(KERN_ERR PRINTK_HEADER));
  1426. /* print failing CCW area */
  1427. len = 0;
  1428. if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
  1429. act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
  1430. len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
  1431. }
  1432. end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
  1433. while (act <= end) {
  1434. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1435. " CCW %p: %08X %08X DAT:",
  1436. act, ((int *) act)[0], ((int *) act)[1]);
  1437. for (count = 0; count < 32 && count < act->count;
  1438. count += sizeof(int))
  1439. len += sprintf(page + len, " %08X",
  1440. ((int *) (addr_t) act->cda)
  1441. [(count>>2)]);
  1442. len += sprintf(page + len, "\n");
  1443. act++;
  1444. }
  1445. /* print last CCWs */
  1446. if (act < last - 2) {
  1447. act = last - 2;
  1448. len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
  1449. }
  1450. while (act <= last) {
  1451. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1452. " CCW %p: %08X %08X DAT:",
  1453. act, ((int *) act)[0], ((int *) act)[1]);
  1454. for (count = 0; count < 32 && count < act->count;
  1455. count += sizeof(int))
  1456. len += sprintf(page + len, " %08X",
  1457. ((int *) (addr_t) act->cda)
  1458. [(count>>2)]);
  1459. len += sprintf(page + len, "\n");
  1460. act++;
  1461. }
  1462. if (len > 0)
  1463. MESSAGE_LOG(KERN_ERR, "%s",
  1464. page + sizeof(KERN_ERR PRINTK_HEADER));
  1465. free_page((unsigned long) page);
  1466. }
  1467. /*
  1468. * max_blocks is dependent on the amount of storage that is available
  1469. * in the static io buffer for each device. Currently each device has
  1470. * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
  1471. * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
  1472. * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
  1473. * addition we have one define extent ccw + 16 bytes of data and one
  1474. * locate record ccw + 16 bytes of data. That makes:
  1475. * (8192 - 24 - 136 - 8 - 16 - 8 - 16) / 16 = 499 blocks at maximum.
  1476. * We want to fit two into the available memory so that we can immediately
  1477. * start the next request if one finishes off. That makes 249.5 blocks
  1478. * for one request. Give a little safety and the result is 240.
  1479. */
  1480. static struct dasd_discipline dasd_eckd_discipline = {
  1481. .owner = THIS_MODULE,
  1482. .name = "ECKD",
  1483. .ebcname = "ECKD",
  1484. .max_blocks = 240,
  1485. .check_device = dasd_eckd_check_characteristics,
  1486. .do_analysis = dasd_eckd_do_analysis,
  1487. .fill_geometry = dasd_eckd_fill_geometry,
  1488. .start_IO = dasd_start_IO,
  1489. .term_IO = dasd_term_IO,
  1490. .format_device = dasd_eckd_format_device,
  1491. .examine_error = dasd_eckd_examine_error,
  1492. .erp_action = dasd_eckd_erp_action,
  1493. .erp_postaction = dasd_eckd_erp_postaction,
  1494. .build_cp = dasd_eckd_build_cp,
  1495. .free_cp = dasd_eckd_free_cp,
  1496. .dump_sense = dasd_eckd_dump_sense,
  1497. .fill_info = dasd_eckd_fill_info,
  1498. };
  1499. static int __init
  1500. dasd_eckd_init(void)
  1501. {
  1502. int ret;
  1503. dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR,
  1504. dasd_eckd_get_attrib);
  1505. dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR,
  1506. dasd_eckd_set_attrib);
  1507. dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD,
  1508. dasd_eckd_performance);
  1509. dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE,
  1510. dasd_eckd_release);
  1511. dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV,
  1512. dasd_eckd_reserve);
  1513. dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK,
  1514. dasd_eckd_steal_lock);
  1515. ASCEBC(dasd_eckd_discipline.ebcname, 4);
  1516. ret = ccw_driver_register(&dasd_eckd_driver);
  1517. if (ret) {
  1518. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
  1519. dasd_eckd_get_attrib);
  1520. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
  1521. dasd_eckd_set_attrib);
  1522. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
  1523. dasd_eckd_performance);
  1524. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
  1525. dasd_eckd_release);
  1526. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
  1527. dasd_eckd_reserve);
  1528. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
  1529. dasd_eckd_steal_lock);
  1530. return ret;
  1531. }
  1532. dasd_generic_auto_online(&dasd_eckd_driver);
  1533. return 0;
  1534. }
  1535. static void __exit
  1536. dasd_eckd_cleanup(void)
  1537. {
  1538. ccw_driver_unregister(&dasd_eckd_driver);
  1539. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
  1540. dasd_eckd_get_attrib);
  1541. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
  1542. dasd_eckd_set_attrib);
  1543. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
  1544. dasd_eckd_performance);
  1545. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
  1546. dasd_eckd_release);
  1547. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
  1548. dasd_eckd_reserve);
  1549. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
  1550. dasd_eckd_steal_lock);
  1551. }
  1552. module_init(dasd_eckd_init);
  1553. module_exit(dasd_eckd_cleanup);
  1554. /*
  1555. * Overrides for Emacs so that we follow Linus's tabbing style.
  1556. * Emacs will notice this stuff at the end of the file and automatically
  1557. * adjust the settings for this buffer only. This must remain at the end
  1558. * of the file.
  1559. * ---------------------------------------------------------------------------
  1560. * Local variables:
  1561. * c-indent-level: 4
  1562. * c-brace-imaginary-offset: 0
  1563. * c-brace-offset: -4
  1564. * c-argdecl-indent: 4
  1565. * c-label-offset: -4
  1566. * c-continued-statement-offset: 4
  1567. * c-continued-brace-offset: 0
  1568. * indent-tabs-mode: 1
  1569. * tab-width: 8
  1570. * End:
  1571. */