dasd_eckd.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  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.74 $
  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. if (req->flags & REQ_FAILFAST)
  1047. set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
  1048. cqr->device = device;
  1049. cqr->expires = 5 * 60 * HZ; /* 5 minutes */
  1050. cqr->lpm = private->path_data.ppm;
  1051. cqr->retries = 256;
  1052. cqr->buildclk = get_clock();
  1053. cqr->status = DASD_CQR_FILLED;
  1054. return cqr;
  1055. }
  1056. static int
  1057. dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
  1058. {
  1059. struct dasd_eckd_private *private;
  1060. struct ccw1 *ccw;
  1061. struct bio *bio;
  1062. struct bio_vec *bv;
  1063. char *dst, *cda;
  1064. unsigned int blksize, blk_per_trk, off;
  1065. sector_t recid;
  1066. int i, status;
  1067. if (!dasd_page_cache)
  1068. goto out;
  1069. private = (struct dasd_eckd_private *) cqr->device->private;
  1070. blksize = cqr->device->bp_block;
  1071. blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
  1072. recid = req->sector >> cqr->device->s2b_shift;
  1073. ccw = cqr->cpaddr;
  1074. /* Skip over define extent & locate record. */
  1075. ccw++;
  1076. if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
  1077. ccw++;
  1078. rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) {
  1079. dst = page_address(bv->bv_page) + bv->bv_offset;
  1080. for (off = 0; off < bv->bv_len; off += blksize) {
  1081. /* Skip locate record. */
  1082. if (private->uses_cdl && recid <= 2*blk_per_trk)
  1083. ccw++;
  1084. if (dst) {
  1085. if (ccw->flags & CCW_FLAG_IDA)
  1086. cda = *((char **)((addr_t) ccw->cda));
  1087. else
  1088. cda = (char *)((addr_t) ccw->cda);
  1089. if (dst != cda) {
  1090. if (rq_data_dir(req) == READ)
  1091. memcpy(dst, cda, bv->bv_len);
  1092. kmem_cache_free(dasd_page_cache,
  1093. (void *)((addr_t)cda & PAGE_MASK));
  1094. }
  1095. dst = NULL;
  1096. }
  1097. ccw++;
  1098. recid++;
  1099. }
  1100. }
  1101. out:
  1102. status = cqr->status == DASD_CQR_DONE;
  1103. dasd_sfree_request(cqr, cqr->device);
  1104. return status;
  1105. }
  1106. static int
  1107. dasd_eckd_fill_info(struct dasd_device * device,
  1108. struct dasd_information2_t * info)
  1109. {
  1110. struct dasd_eckd_private *private;
  1111. private = (struct dasd_eckd_private *) device->private;
  1112. info->label_block = 2;
  1113. info->FBA_layout = private->uses_cdl ? 0 : 1;
  1114. info->format = private->uses_cdl ? DASD_FORMAT_CDL : DASD_FORMAT_LDL;
  1115. info->characteristics_size = sizeof(struct dasd_eckd_characteristics);
  1116. memcpy(info->characteristics, &private->rdc_data,
  1117. sizeof(struct dasd_eckd_characteristics));
  1118. info->confdata_size = sizeof (struct dasd_eckd_confdata);
  1119. memcpy(info->configuration_data, &private->conf_data,
  1120. sizeof (struct dasd_eckd_confdata));
  1121. return 0;
  1122. }
  1123. /*
  1124. * SECTION: ioctl functions for eckd devices.
  1125. */
  1126. /*
  1127. * Release device ioctl.
  1128. * Buils a channel programm to releases a prior reserved
  1129. * (see dasd_eckd_reserve) device.
  1130. */
  1131. static int
  1132. dasd_eckd_release(struct block_device *bdev, int no, long args)
  1133. {
  1134. struct dasd_device *device;
  1135. struct dasd_ccw_req *cqr;
  1136. int rc;
  1137. if (!capable(CAP_SYS_ADMIN))
  1138. return -EACCES;
  1139. device = bdev->bd_disk->private_data;
  1140. if (device == NULL)
  1141. return -ENODEV;
  1142. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1143. 1, 32, device);
  1144. if (IS_ERR(cqr)) {
  1145. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1146. "Could not allocate initialization request");
  1147. return PTR_ERR(cqr);
  1148. }
  1149. cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
  1150. cqr->cpaddr->flags |= CCW_FLAG_SLI;
  1151. cqr->cpaddr->count = 32;
  1152. cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
  1153. cqr->device = device;
  1154. clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
  1155. set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
  1156. cqr->retries = 0;
  1157. cqr->expires = 2 * HZ;
  1158. cqr->buildclk = get_clock();
  1159. cqr->status = DASD_CQR_FILLED;
  1160. rc = dasd_sleep_on_immediatly(cqr);
  1161. dasd_sfree_request(cqr, cqr->device);
  1162. return rc;
  1163. }
  1164. /*
  1165. * Reserve device ioctl.
  1166. * Options are set to 'synchronous wait for interrupt' and
  1167. * 'timeout the request'. This leads to a terminate IO if
  1168. * the interrupt is outstanding for a certain time.
  1169. */
  1170. static int
  1171. dasd_eckd_reserve(struct block_device *bdev, int no, long args)
  1172. {
  1173. struct dasd_device *device;
  1174. struct dasd_ccw_req *cqr;
  1175. int rc;
  1176. if (!capable(CAP_SYS_ADMIN))
  1177. return -EACCES;
  1178. device = bdev->bd_disk->private_data;
  1179. if (device == NULL)
  1180. return -ENODEV;
  1181. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1182. 1, 32, device);
  1183. if (IS_ERR(cqr)) {
  1184. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1185. "Could not allocate initialization request");
  1186. return PTR_ERR(cqr);
  1187. }
  1188. cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
  1189. cqr->cpaddr->flags |= CCW_FLAG_SLI;
  1190. cqr->cpaddr->count = 32;
  1191. cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
  1192. cqr->device = device;
  1193. clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
  1194. set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
  1195. cqr->retries = 0;
  1196. cqr->expires = 2 * HZ;
  1197. cqr->buildclk = get_clock();
  1198. cqr->status = DASD_CQR_FILLED;
  1199. rc = dasd_sleep_on_immediatly(cqr);
  1200. dasd_sfree_request(cqr, cqr->device);
  1201. return rc;
  1202. }
  1203. /*
  1204. * Steal lock ioctl - unconditional reserve device.
  1205. * Buils a channel programm to break a device's reservation.
  1206. * (unconditional reserve)
  1207. */
  1208. static int
  1209. dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
  1210. {
  1211. struct dasd_device *device;
  1212. struct dasd_ccw_req *cqr;
  1213. int rc;
  1214. if (!capable(CAP_SYS_ADMIN))
  1215. return -EACCES;
  1216. device = bdev->bd_disk->private_data;
  1217. if (device == NULL)
  1218. return -ENODEV;
  1219. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1220. 1, 32, device);
  1221. if (IS_ERR(cqr)) {
  1222. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1223. "Could not allocate initialization request");
  1224. return PTR_ERR(cqr);
  1225. }
  1226. cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
  1227. cqr->cpaddr->flags |= CCW_FLAG_SLI;
  1228. cqr->cpaddr->count = 32;
  1229. cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
  1230. cqr->device = device;
  1231. clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
  1232. set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
  1233. cqr->retries = 0;
  1234. cqr->expires = 2 * HZ;
  1235. cqr->buildclk = get_clock();
  1236. cqr->status = DASD_CQR_FILLED;
  1237. rc = dasd_sleep_on_immediatly(cqr);
  1238. dasd_sfree_request(cqr, cqr->device);
  1239. return rc;
  1240. }
  1241. /*
  1242. * Read performance statistics
  1243. */
  1244. static int
  1245. dasd_eckd_performance(struct block_device *bdev, int no, long args)
  1246. {
  1247. struct dasd_device *device;
  1248. struct dasd_psf_prssd_data *prssdp;
  1249. struct dasd_rssd_perf_stats_t *stats;
  1250. struct dasd_ccw_req *cqr;
  1251. struct ccw1 *ccw;
  1252. int rc;
  1253. device = bdev->bd_disk->private_data;
  1254. if (device == NULL)
  1255. return -ENODEV;
  1256. cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
  1257. 1 /* PSF */ + 1 /* RSSD */ ,
  1258. (sizeof (struct dasd_psf_prssd_data) +
  1259. sizeof (struct dasd_rssd_perf_stats_t)),
  1260. device);
  1261. if (IS_ERR(cqr)) {
  1262. DEV_MESSAGE(KERN_WARNING, device, "%s",
  1263. "Could not allocate initialization request");
  1264. return PTR_ERR(cqr);
  1265. }
  1266. cqr->device = device;
  1267. cqr->retries = 0;
  1268. cqr->expires = 10 * HZ;
  1269. /* Prepare for Read Subsystem Data */
  1270. prssdp = (struct dasd_psf_prssd_data *) cqr->data;
  1271. memset(prssdp, 0, sizeof (struct dasd_psf_prssd_data));
  1272. prssdp->order = PSF_ORDER_PRSSD;
  1273. prssdp->suborder = 0x01; /* Perfomance Statistics */
  1274. prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */
  1275. ccw = cqr->cpaddr;
  1276. ccw->cmd_code = DASD_ECKD_CCW_PSF;
  1277. ccw->count = sizeof (struct dasd_psf_prssd_data);
  1278. ccw->flags |= CCW_FLAG_CC;
  1279. ccw->cda = (__u32)(addr_t) prssdp;
  1280. /* Read Subsystem Data - Performance Statistics */
  1281. stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
  1282. memset(stats, 0, sizeof (struct dasd_rssd_perf_stats_t));
  1283. ccw++;
  1284. ccw->cmd_code = DASD_ECKD_CCW_RSSD;
  1285. ccw->count = sizeof (struct dasd_rssd_perf_stats_t);
  1286. ccw->cda = (__u32)(addr_t) stats;
  1287. cqr->buildclk = get_clock();
  1288. cqr->status = DASD_CQR_FILLED;
  1289. rc = dasd_sleep_on(cqr);
  1290. if (rc == 0) {
  1291. /* Prepare for Read Subsystem Data */
  1292. prssdp = (struct dasd_psf_prssd_data *) cqr->data;
  1293. stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
  1294. rc = copy_to_user((long __user *) args, (long *) stats,
  1295. sizeof(struct dasd_rssd_perf_stats_t));
  1296. }
  1297. dasd_sfree_request(cqr, cqr->device);
  1298. return rc;
  1299. }
  1300. /*
  1301. * Get attributes (cache operations)
  1302. * Returnes the cache attributes used in Define Extend (DE).
  1303. */
  1304. static int
  1305. dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
  1306. {
  1307. struct dasd_device *device;
  1308. struct dasd_eckd_private *private;
  1309. struct attrib_data_t attrib;
  1310. int rc;
  1311. if (!capable(CAP_SYS_ADMIN))
  1312. return -EACCES;
  1313. if (!args)
  1314. return -EINVAL;
  1315. device = bdev->bd_disk->private_data;
  1316. if (device == NULL)
  1317. return -ENODEV;
  1318. private = (struct dasd_eckd_private *) device->private;
  1319. attrib = private->attrib;
  1320. rc = copy_to_user((long __user *) args, (long *) &attrib,
  1321. sizeof (struct attrib_data_t));
  1322. return rc;
  1323. }
  1324. /*
  1325. * Set attributes (cache operations)
  1326. * Stores the attributes for cache operation to be used in Define Extend (DE).
  1327. */
  1328. static int
  1329. dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
  1330. {
  1331. struct dasd_device *device;
  1332. struct dasd_eckd_private *private;
  1333. struct attrib_data_t attrib;
  1334. if (!capable(CAP_SYS_ADMIN))
  1335. return -EACCES;
  1336. if (!args)
  1337. return -EINVAL;
  1338. device = bdev->bd_disk->private_data;
  1339. if (device == NULL)
  1340. return -ENODEV;
  1341. if (copy_from_user(&attrib, (void __user *) args,
  1342. sizeof (struct attrib_data_t))) {
  1343. return -EFAULT;
  1344. }
  1345. private = (struct dasd_eckd_private *) device->private;
  1346. private->attrib = attrib;
  1347. DEV_MESSAGE(KERN_INFO, device,
  1348. "cache operation mode set to %x (%i cylinder prestage)",
  1349. private->attrib.operation, private->attrib.nr_cyl);
  1350. return 0;
  1351. }
  1352. /*
  1353. * Print sense data and related channel program.
  1354. * Parts are printed because printk buffer is only 1024 bytes.
  1355. */
  1356. static void
  1357. dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
  1358. struct irb *irb)
  1359. {
  1360. char *page;
  1361. struct ccw1 *act, *end, *last;
  1362. int len, sl, sct, count;
  1363. page = (char *) get_zeroed_page(GFP_ATOMIC);
  1364. if (page == NULL) {
  1365. DEV_MESSAGE(KERN_ERR, device, " %s",
  1366. "No memory to dump sense data");
  1367. return;
  1368. }
  1369. len = sprintf(page, KERN_ERR PRINTK_HEADER
  1370. " I/O status report for device %s:\n",
  1371. device->cdev->dev.bus_id);
  1372. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1373. " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
  1374. irb->scsw.cstat, irb->scsw.dstat);
  1375. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1376. " device %s: Failing CCW: %p\n",
  1377. device->cdev->dev.bus_id,
  1378. (void *) (addr_t) irb->scsw.cpa);
  1379. if (irb->esw.esw0.erw.cons) {
  1380. for (sl = 0; sl < 4; sl++) {
  1381. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1382. " Sense(hex) %2d-%2d:",
  1383. (8 * sl), ((8 * sl) + 7));
  1384. for (sct = 0; sct < 8; sct++) {
  1385. len += sprintf(page + len, " %02x",
  1386. irb->ecw[8 * sl + sct]);
  1387. }
  1388. len += sprintf(page + len, "\n");
  1389. }
  1390. if (irb->ecw[27] & DASD_SENSE_BIT_0) {
  1391. /* 24 Byte Sense Data */
  1392. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1393. " 24 Byte: %x MSG %x, "
  1394. "%s MSGb to SYSOP\n",
  1395. irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
  1396. irb->ecw[1] & 0x10 ? "" : "no");
  1397. } else {
  1398. /* 32 Byte Sense Data */
  1399. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1400. " 32 Byte: Format: %x "
  1401. "Exception class %x\n",
  1402. irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
  1403. }
  1404. } else {
  1405. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1406. " SORRY - NO VALID SENSE AVAILABLE\n");
  1407. }
  1408. MESSAGE_LOG(KERN_ERR, "%s",
  1409. page + sizeof(KERN_ERR PRINTK_HEADER));
  1410. /* dump the Channel Program */
  1411. /* print first CCWs (maximum 8) */
  1412. act = req->cpaddr;
  1413. for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
  1414. end = min(act + 8, last);
  1415. len = sprintf(page, KERN_ERR PRINTK_HEADER
  1416. " Related CP in req: %p\n", req);
  1417. while (act <= end) {
  1418. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1419. " CCW %p: %08X %08X DAT:",
  1420. act, ((int *) act)[0], ((int *) act)[1]);
  1421. for (count = 0; count < 32 && count < act->count;
  1422. count += sizeof(int))
  1423. len += sprintf(page + len, " %08X",
  1424. ((int *) (addr_t) act->cda)
  1425. [(count>>2)]);
  1426. len += sprintf(page + len, "\n");
  1427. act++;
  1428. }
  1429. MESSAGE_LOG(KERN_ERR, "%s",
  1430. page + sizeof(KERN_ERR PRINTK_HEADER));
  1431. /* print failing CCW area */
  1432. len = 0;
  1433. if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
  1434. act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
  1435. len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
  1436. }
  1437. end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
  1438. while (act <= end) {
  1439. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1440. " CCW %p: %08X %08X DAT:",
  1441. act, ((int *) act)[0], ((int *) act)[1]);
  1442. for (count = 0; count < 32 && count < act->count;
  1443. count += sizeof(int))
  1444. len += sprintf(page + len, " %08X",
  1445. ((int *) (addr_t) act->cda)
  1446. [(count>>2)]);
  1447. len += sprintf(page + len, "\n");
  1448. act++;
  1449. }
  1450. /* print last CCWs */
  1451. if (act < last - 2) {
  1452. act = last - 2;
  1453. len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
  1454. }
  1455. while (act <= last) {
  1456. len += sprintf(page + len, KERN_ERR PRINTK_HEADER
  1457. " CCW %p: %08X %08X DAT:",
  1458. act, ((int *) act)[0], ((int *) act)[1]);
  1459. for (count = 0; count < 32 && count < act->count;
  1460. count += sizeof(int))
  1461. len += sprintf(page + len, " %08X",
  1462. ((int *) (addr_t) act->cda)
  1463. [(count>>2)]);
  1464. len += sprintf(page + len, "\n");
  1465. act++;
  1466. }
  1467. if (len > 0)
  1468. MESSAGE_LOG(KERN_ERR, "%s",
  1469. page + sizeof(KERN_ERR PRINTK_HEADER));
  1470. free_page((unsigned long) page);
  1471. }
  1472. /*
  1473. * max_blocks is dependent on the amount of storage that is available
  1474. * in the static io buffer for each device. Currently each device has
  1475. * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
  1476. * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
  1477. * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
  1478. * addition we have one define extent ccw + 16 bytes of data and one
  1479. * locate record ccw + 16 bytes of data. That makes:
  1480. * (8192 - 24 - 136 - 8 - 16 - 8 - 16) / 16 = 499 blocks at maximum.
  1481. * We want to fit two into the available memory so that we can immediately
  1482. * start the next request if one finishes off. That makes 249.5 blocks
  1483. * for one request. Give a little safety and the result is 240.
  1484. */
  1485. static struct dasd_discipline dasd_eckd_discipline = {
  1486. .owner = THIS_MODULE,
  1487. .name = "ECKD",
  1488. .ebcname = "ECKD",
  1489. .max_blocks = 240,
  1490. .check_device = dasd_eckd_check_characteristics,
  1491. .do_analysis = dasd_eckd_do_analysis,
  1492. .fill_geometry = dasd_eckd_fill_geometry,
  1493. .start_IO = dasd_start_IO,
  1494. .term_IO = dasd_term_IO,
  1495. .format_device = dasd_eckd_format_device,
  1496. .examine_error = dasd_eckd_examine_error,
  1497. .erp_action = dasd_eckd_erp_action,
  1498. .erp_postaction = dasd_eckd_erp_postaction,
  1499. .build_cp = dasd_eckd_build_cp,
  1500. .free_cp = dasd_eckd_free_cp,
  1501. .dump_sense = dasd_eckd_dump_sense,
  1502. .fill_info = dasd_eckd_fill_info,
  1503. };
  1504. static int __init
  1505. dasd_eckd_init(void)
  1506. {
  1507. int ret;
  1508. dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR,
  1509. dasd_eckd_get_attrib);
  1510. dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR,
  1511. dasd_eckd_set_attrib);
  1512. dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD,
  1513. dasd_eckd_performance);
  1514. dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE,
  1515. dasd_eckd_release);
  1516. dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV,
  1517. dasd_eckd_reserve);
  1518. dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK,
  1519. dasd_eckd_steal_lock);
  1520. ASCEBC(dasd_eckd_discipline.ebcname, 4);
  1521. ret = ccw_driver_register(&dasd_eckd_driver);
  1522. if (ret) {
  1523. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
  1524. dasd_eckd_get_attrib);
  1525. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
  1526. dasd_eckd_set_attrib);
  1527. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
  1528. dasd_eckd_performance);
  1529. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
  1530. dasd_eckd_release);
  1531. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
  1532. dasd_eckd_reserve);
  1533. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
  1534. dasd_eckd_steal_lock);
  1535. return ret;
  1536. }
  1537. dasd_generic_auto_online(&dasd_eckd_driver);
  1538. return 0;
  1539. }
  1540. static void __exit
  1541. dasd_eckd_cleanup(void)
  1542. {
  1543. ccw_driver_unregister(&dasd_eckd_driver);
  1544. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
  1545. dasd_eckd_get_attrib);
  1546. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
  1547. dasd_eckd_set_attrib);
  1548. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
  1549. dasd_eckd_performance);
  1550. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
  1551. dasd_eckd_release);
  1552. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
  1553. dasd_eckd_reserve);
  1554. dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
  1555. dasd_eckd_steal_lock);
  1556. }
  1557. module_init(dasd_eckd_init);
  1558. module_exit(dasd_eckd_cleanup);
  1559. /*
  1560. * Overrides for Emacs so that we follow Linus's tabbing style.
  1561. * Emacs will notice this stuff at the end of the file and automatically
  1562. * adjust the settings for this buffer only. This must remain at the end
  1563. * of the file.
  1564. * ---------------------------------------------------------------------------
  1565. * Local variables:
  1566. * c-indent-level: 4
  1567. * c-brace-imaginary-offset: 0
  1568. * c-brace-offset: -4
  1569. * c-argdecl-indent: 4
  1570. * c-label-offset: -4
  1571. * c-continued-statement-offset: 4
  1572. * c-continued-brace-offset: 0
  1573. * indent-tabs-mode: 1
  1574. * tab-width: 8
  1575. * End:
  1576. */