dasd_eckd.c 48 KB

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