dasd_devmap.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. /*
  2. * File...........: linux/drivers/s390/block/dasd_devmap.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-2001
  9. *
  10. * Device mapping and dasd= parameter parsing functions. All devmap
  11. * functions may not be called from interrupt context. In particular
  12. * dasd_get_device is a no-no from interrupt context.
  13. *
  14. */
  15. #define KMSG_COMPONENT "dasd"
  16. #include <linux/ctype.h>
  17. #include <linux/init.h>
  18. #include <linux/module.h>
  19. #include <linux/slab.h>
  20. #include <asm/debug.h>
  21. #include <asm/uaccess.h>
  22. #include <asm/ipl.h>
  23. /* This is ugly... */
  24. #define PRINTK_HEADER "dasd_devmap:"
  25. #define DASD_BUS_ID_SIZE 20
  26. #include "dasd_int.h"
  27. struct kmem_cache *dasd_page_cache;
  28. EXPORT_SYMBOL_GPL(dasd_page_cache);
  29. /*
  30. * dasd_devmap_t is used to store the features and the relation
  31. * between device number and device index. To find a dasd_devmap_t
  32. * that corresponds to a device number of a device index each
  33. * dasd_devmap_t is added to two linked lists, one to search by
  34. * the device number and one to search by the device index. As
  35. * soon as big minor numbers are available the device index list
  36. * can be removed since the device number will then be identical
  37. * to the device index.
  38. */
  39. struct dasd_devmap {
  40. struct list_head list;
  41. char bus_id[DASD_BUS_ID_SIZE];
  42. unsigned int devindex;
  43. unsigned short features;
  44. struct dasd_device *device;
  45. };
  46. /*
  47. * Parameter parsing functions for dasd= parameter. The syntax is:
  48. * <devno> : (0x)?[0-9a-fA-F]+
  49. * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
  50. * <feature> : ro
  51. * <feature_list> : \(<feature>(:<feature>)*\)
  52. * <devno-range> : <devno>(-<devno>)?<feature_list>?
  53. * <busid-range> : <busid>(-<busid>)?<feature_list>?
  54. * <devices> : <devno-range>|<busid-range>
  55. * <dasd_module> : dasd_diag_mod|dasd_eckd_mod|dasd_fba_mod
  56. *
  57. * <dasd> : autodetect|probeonly|<devices>(,<devices>)*
  58. */
  59. int dasd_probeonly = 0; /* is true, when probeonly mode is active */
  60. int dasd_autodetect = 0; /* is true, when autodetection is active */
  61. int dasd_nopav = 0; /* is true, when PAV is disabled */
  62. EXPORT_SYMBOL_GPL(dasd_nopav);
  63. int dasd_nofcx; /* disable High Performance Ficon */
  64. EXPORT_SYMBOL_GPL(dasd_nofcx);
  65. /*
  66. * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
  67. * it is named 'dasd' to directly be filled by insmod with the comma separated
  68. * strings when running as a module.
  69. */
  70. static char *dasd[256];
  71. module_param_array(dasd, charp, NULL, 0);
  72. /*
  73. * Single spinlock to protect devmap and servermap structures and lists.
  74. */
  75. static DEFINE_SPINLOCK(dasd_devmap_lock);
  76. /*
  77. * Hash lists for devmap structures.
  78. */
  79. static struct list_head dasd_hashlists[256];
  80. int dasd_max_devindex;
  81. static struct dasd_devmap *dasd_add_busid(const char *, int);
  82. static inline int
  83. dasd_hash_busid(const char *bus_id)
  84. {
  85. int hash, i;
  86. hash = 0;
  87. for (i = 0; (i < DASD_BUS_ID_SIZE) && *bus_id; i++, bus_id++)
  88. hash += *bus_id;
  89. return hash & 0xff;
  90. }
  91. #ifndef MODULE
  92. /*
  93. * The parameter parsing functions for builtin-drivers are called
  94. * before kmalloc works. Store the pointers to the parameters strings
  95. * into dasd[] for later processing.
  96. */
  97. static int __init
  98. dasd_call_setup(char *str)
  99. {
  100. static int count = 0;
  101. if (count < 256)
  102. dasd[count++] = str;
  103. return 1;
  104. }
  105. __setup ("dasd=", dasd_call_setup);
  106. #endif /* #ifndef MODULE */
  107. #define DASD_IPLDEV "ipldev"
  108. /*
  109. * Read a device busid/devno from a string.
  110. */
  111. static int
  112. dasd_busid(char **str, int *id0, int *id1, int *devno)
  113. {
  114. int val, old_style;
  115. /* Interpret ipldev busid */
  116. if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) {
  117. if (ipl_info.type != IPL_TYPE_CCW) {
  118. pr_err("The IPL device is not a CCW device\n");
  119. return -EINVAL;
  120. }
  121. *id0 = 0;
  122. *id1 = ipl_info.data.ccw.dev_id.ssid;
  123. *devno = ipl_info.data.ccw.dev_id.devno;
  124. *str += strlen(DASD_IPLDEV);
  125. return 0;
  126. }
  127. /* check for leading '0x' */
  128. old_style = 0;
  129. if ((*str)[0] == '0' && (*str)[1] == 'x') {
  130. *str += 2;
  131. old_style = 1;
  132. }
  133. if (!isxdigit((*str)[0])) /* We require at least one hex digit */
  134. return -EINVAL;
  135. val = simple_strtoul(*str, str, 16);
  136. if (old_style || (*str)[0] != '.') {
  137. *id0 = *id1 = 0;
  138. if (val < 0 || val > 0xffff)
  139. return -EINVAL;
  140. *devno = val;
  141. return 0;
  142. }
  143. /* New style x.y.z busid */
  144. if (val < 0 || val > 0xff)
  145. return -EINVAL;
  146. *id0 = val;
  147. (*str)++;
  148. if (!isxdigit((*str)[0])) /* We require at least one hex digit */
  149. return -EINVAL;
  150. val = simple_strtoul(*str, str, 16);
  151. if (val < 0 || val > 0xff || (*str)++[0] != '.')
  152. return -EINVAL;
  153. *id1 = val;
  154. if (!isxdigit((*str)[0])) /* We require at least one hex digit */
  155. return -EINVAL;
  156. val = simple_strtoul(*str, str, 16);
  157. if (val < 0 || val > 0xffff)
  158. return -EINVAL;
  159. *devno = val;
  160. return 0;
  161. }
  162. /*
  163. * Read colon separated list of dasd features. Currently there is
  164. * only one: "ro" for read-only devices. The default feature set
  165. * is empty (value 0).
  166. */
  167. static int
  168. dasd_feature_list(char *str, char **endp)
  169. {
  170. int features, len, rc;
  171. rc = 0;
  172. if (*str != '(') {
  173. *endp = str;
  174. return DASD_FEATURE_DEFAULT;
  175. }
  176. str++;
  177. features = 0;
  178. while (1) {
  179. for (len = 0;
  180. str[len] && str[len] != ':' && str[len] != ')'; len++);
  181. if (len == 2 && !strncmp(str, "ro", 2))
  182. features |= DASD_FEATURE_READONLY;
  183. else if (len == 4 && !strncmp(str, "diag", 4))
  184. features |= DASD_FEATURE_USEDIAG;
  185. else if (len == 3 && !strncmp(str, "raw", 3))
  186. features |= DASD_FEATURE_USERAW;
  187. else if (len == 6 && !strncmp(str, "erplog", 6))
  188. features |= DASD_FEATURE_ERPLOG;
  189. else if (len == 8 && !strncmp(str, "failfast", 8))
  190. features |= DASD_FEATURE_FAILFAST;
  191. else {
  192. pr_warning("%*s is not a supported device option\n",
  193. len, str);
  194. rc = -EINVAL;
  195. }
  196. str += len;
  197. if (*str != ':')
  198. break;
  199. str++;
  200. }
  201. if (*str != ')') {
  202. pr_warning("A closing parenthesis ')' is missing in the "
  203. "dasd= parameter\n");
  204. rc = -EINVAL;
  205. } else
  206. str++;
  207. *endp = str;
  208. if (rc != 0)
  209. return rc;
  210. return features;
  211. }
  212. /*
  213. * Try to match the first element on the comma separated parse string
  214. * with one of the known keywords. If a keyword is found, take the approprate
  215. * action and return a pointer to the residual string. If the first element
  216. * could not be matched to any keyword then return an error code.
  217. */
  218. static char *
  219. dasd_parse_keyword( char *parsestring ) {
  220. char *nextcomma, *residual_str;
  221. int length;
  222. nextcomma = strchr(parsestring,',');
  223. if (nextcomma) {
  224. length = nextcomma - parsestring;
  225. residual_str = nextcomma + 1;
  226. } else {
  227. length = strlen(parsestring);
  228. residual_str = parsestring + length;
  229. }
  230. if (strncmp("autodetect", parsestring, length) == 0) {
  231. dasd_autodetect = 1;
  232. pr_info("The autodetection mode has been activated\n");
  233. return residual_str;
  234. }
  235. if (strncmp("probeonly", parsestring, length) == 0) {
  236. dasd_probeonly = 1;
  237. pr_info("The probeonly mode has been activated\n");
  238. return residual_str;
  239. }
  240. if (strncmp("nopav", parsestring, length) == 0) {
  241. if (MACHINE_IS_VM)
  242. pr_info("'nopav' is not supported on z/VM\n");
  243. else {
  244. dasd_nopav = 1;
  245. pr_info("PAV support has be deactivated\n");
  246. }
  247. return residual_str;
  248. }
  249. if (strncmp("nofcx", parsestring, length) == 0) {
  250. dasd_nofcx = 1;
  251. pr_info("High Performance FICON support has been "
  252. "deactivated\n");
  253. return residual_str;
  254. }
  255. if (strncmp("fixedbuffers", parsestring, length) == 0) {
  256. if (dasd_page_cache)
  257. return residual_str;
  258. dasd_page_cache =
  259. kmem_cache_create("dasd_page_cache", PAGE_SIZE,
  260. PAGE_SIZE, SLAB_CACHE_DMA,
  261. NULL);
  262. if (!dasd_page_cache)
  263. DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, "
  264. "fixed buffer mode disabled.");
  265. else
  266. DBF_EVENT(DBF_INFO, "%s",
  267. "turning on fixed buffer mode");
  268. return residual_str;
  269. }
  270. return ERR_PTR(-EINVAL);
  271. }
  272. /*
  273. * Try to interprete the first element on the comma separated parse string
  274. * as a device number or a range of devices. If the interpretation is
  275. * successful, create the matching dasd_devmap entries and return a pointer
  276. * to the residual string.
  277. * If interpretation fails or in case of an error, return an error code.
  278. */
  279. static char *
  280. dasd_parse_range( char *parsestring ) {
  281. struct dasd_devmap *devmap;
  282. int from, from_id0, from_id1;
  283. int to, to_id0, to_id1;
  284. int features, rc;
  285. char bus_id[DASD_BUS_ID_SIZE+1], *str;
  286. str = parsestring;
  287. rc = dasd_busid(&str, &from_id0, &from_id1, &from);
  288. if (rc == 0) {
  289. to = from;
  290. to_id0 = from_id0;
  291. to_id1 = from_id1;
  292. if (*str == '-') {
  293. str++;
  294. rc = dasd_busid(&str, &to_id0, &to_id1, &to);
  295. }
  296. }
  297. if (rc == 0 &&
  298. (from_id0 != to_id0 || from_id1 != to_id1 || from > to))
  299. rc = -EINVAL;
  300. if (rc) {
  301. pr_err("%s is not a valid device range\n", parsestring);
  302. return ERR_PTR(rc);
  303. }
  304. features = dasd_feature_list(str, &str);
  305. if (features < 0)
  306. return ERR_PTR(-EINVAL);
  307. /* each device in dasd= parameter should be set initially online */
  308. features |= DASD_FEATURE_INITIAL_ONLINE;
  309. while (from <= to) {
  310. sprintf(bus_id, "%01x.%01x.%04x",
  311. from_id0, from_id1, from++);
  312. devmap = dasd_add_busid(bus_id, features);
  313. if (IS_ERR(devmap))
  314. return (char *)devmap;
  315. }
  316. if (*str == ',')
  317. return str + 1;
  318. if (*str == '\0')
  319. return str;
  320. pr_warning("The dasd= parameter value %s has an invalid ending\n",
  321. str);
  322. return ERR_PTR(-EINVAL);
  323. }
  324. static char *
  325. dasd_parse_next_element( char *parsestring ) {
  326. char * residual_str;
  327. residual_str = dasd_parse_keyword(parsestring);
  328. if (!IS_ERR(residual_str))
  329. return residual_str;
  330. residual_str = dasd_parse_range(parsestring);
  331. return residual_str;
  332. }
  333. /*
  334. * Parse parameters stored in dasd[]
  335. * The 'dasd=...' parameter allows to specify a comma separated list of
  336. * keywords and device ranges. When the dasd driver is build into the kernel,
  337. * the complete list will be stored as one element of the dasd[] array.
  338. * When the dasd driver is build as a module, then the list is broken into
  339. * it's elements and each dasd[] entry contains one element.
  340. */
  341. int
  342. dasd_parse(void)
  343. {
  344. int rc, i;
  345. char *parsestring;
  346. rc = 0;
  347. for (i = 0; i < 256; i++) {
  348. if (dasd[i] == NULL)
  349. break;
  350. parsestring = dasd[i];
  351. /* loop over the comma separated list in the parsestring */
  352. while (*parsestring) {
  353. parsestring = dasd_parse_next_element(parsestring);
  354. if(IS_ERR(parsestring)) {
  355. rc = PTR_ERR(parsestring);
  356. break;
  357. }
  358. }
  359. if (rc) {
  360. DBF_EVENT(DBF_ALERT, "%s", "invalid range found");
  361. break;
  362. }
  363. }
  364. return rc;
  365. }
  366. /*
  367. * Add a devmap for the device specified by busid. It is possible that
  368. * the devmap already exists (dasd= parameter). The order of the devices
  369. * added through this function will define the kdevs for the individual
  370. * devices.
  371. */
  372. static struct dasd_devmap *
  373. dasd_add_busid(const char *bus_id, int features)
  374. {
  375. struct dasd_devmap *devmap, *new, *tmp;
  376. int hash;
  377. new = (struct dasd_devmap *)
  378. kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
  379. if (!new)
  380. return ERR_PTR(-ENOMEM);
  381. spin_lock(&dasd_devmap_lock);
  382. devmap = NULL;
  383. hash = dasd_hash_busid(bus_id);
  384. list_for_each_entry(tmp, &dasd_hashlists[hash], list)
  385. if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
  386. devmap = tmp;
  387. break;
  388. }
  389. if (!devmap) {
  390. /* This bus_id is new. */
  391. new->devindex = dasd_max_devindex++;
  392. strncpy(new->bus_id, bus_id, DASD_BUS_ID_SIZE);
  393. new->features = features;
  394. new->device = NULL;
  395. list_add(&new->list, &dasd_hashlists[hash]);
  396. devmap = new;
  397. new = NULL;
  398. }
  399. spin_unlock(&dasd_devmap_lock);
  400. kfree(new);
  401. return devmap;
  402. }
  403. /*
  404. * Find devmap for device with given bus_id.
  405. */
  406. static struct dasd_devmap *
  407. dasd_find_busid(const char *bus_id)
  408. {
  409. struct dasd_devmap *devmap, *tmp;
  410. int hash;
  411. spin_lock(&dasd_devmap_lock);
  412. devmap = ERR_PTR(-ENODEV);
  413. hash = dasd_hash_busid(bus_id);
  414. list_for_each_entry(tmp, &dasd_hashlists[hash], list) {
  415. if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
  416. devmap = tmp;
  417. break;
  418. }
  419. }
  420. spin_unlock(&dasd_devmap_lock);
  421. return devmap;
  422. }
  423. /*
  424. * Check if busid has been added to the list of dasd ranges.
  425. */
  426. int
  427. dasd_busid_known(const char *bus_id)
  428. {
  429. return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0;
  430. }
  431. /*
  432. * Forget all about the device numbers added so far.
  433. * This may only be called at module unload or system shutdown.
  434. */
  435. static void
  436. dasd_forget_ranges(void)
  437. {
  438. struct dasd_devmap *devmap, *n;
  439. int i;
  440. spin_lock(&dasd_devmap_lock);
  441. for (i = 0; i < 256; i++) {
  442. list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) {
  443. BUG_ON(devmap->device != NULL);
  444. list_del(&devmap->list);
  445. kfree(devmap);
  446. }
  447. }
  448. spin_unlock(&dasd_devmap_lock);
  449. }
  450. /*
  451. * Find the device struct by its device index.
  452. */
  453. struct dasd_device *
  454. dasd_device_from_devindex(int devindex)
  455. {
  456. struct dasd_devmap *devmap, *tmp;
  457. struct dasd_device *device;
  458. int i;
  459. spin_lock(&dasd_devmap_lock);
  460. devmap = NULL;
  461. for (i = 0; (i < 256) && !devmap; i++)
  462. list_for_each_entry(tmp, &dasd_hashlists[i], list)
  463. if (tmp->devindex == devindex) {
  464. /* Found the devmap for the device. */
  465. devmap = tmp;
  466. break;
  467. }
  468. if (devmap && devmap->device) {
  469. device = devmap->device;
  470. dasd_get_device(device);
  471. } else
  472. device = ERR_PTR(-ENODEV);
  473. spin_unlock(&dasd_devmap_lock);
  474. return device;
  475. }
  476. /*
  477. * Return devmap for cdev. If no devmap exists yet, create one and
  478. * connect it to the cdev.
  479. */
  480. static struct dasd_devmap *
  481. dasd_devmap_from_cdev(struct ccw_device *cdev)
  482. {
  483. struct dasd_devmap *devmap;
  484. devmap = dasd_find_busid(dev_name(&cdev->dev));
  485. if (IS_ERR(devmap))
  486. devmap = dasd_add_busid(dev_name(&cdev->dev),
  487. DASD_FEATURE_DEFAULT);
  488. return devmap;
  489. }
  490. /*
  491. * Create a dasd device structure for cdev.
  492. */
  493. struct dasd_device *
  494. dasd_create_device(struct ccw_device *cdev)
  495. {
  496. struct dasd_devmap *devmap;
  497. struct dasd_device *device;
  498. unsigned long flags;
  499. int rc;
  500. devmap = dasd_devmap_from_cdev(cdev);
  501. if (IS_ERR(devmap))
  502. return (void *) devmap;
  503. device = dasd_alloc_device();
  504. if (IS_ERR(device))
  505. return device;
  506. atomic_set(&device->ref_count, 3);
  507. spin_lock(&dasd_devmap_lock);
  508. if (!devmap->device) {
  509. devmap->device = device;
  510. device->devindex = devmap->devindex;
  511. device->features = devmap->features;
  512. get_device(&cdev->dev);
  513. device->cdev = cdev;
  514. rc = 0;
  515. } else
  516. /* Someone else was faster. */
  517. rc = -EBUSY;
  518. spin_unlock(&dasd_devmap_lock);
  519. if (rc) {
  520. dasd_free_device(device);
  521. return ERR_PTR(rc);
  522. }
  523. spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
  524. dev_set_drvdata(&cdev->dev, device);
  525. spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
  526. return device;
  527. }
  528. /*
  529. * Wait queue for dasd_delete_device waits.
  530. */
  531. static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq);
  532. /*
  533. * Remove a dasd device structure. The passed referenced
  534. * is destroyed.
  535. */
  536. void
  537. dasd_delete_device(struct dasd_device *device)
  538. {
  539. struct ccw_device *cdev;
  540. struct dasd_devmap *devmap;
  541. unsigned long flags;
  542. /* First remove device pointer from devmap. */
  543. devmap = dasd_find_busid(dev_name(&device->cdev->dev));
  544. BUG_ON(IS_ERR(devmap));
  545. spin_lock(&dasd_devmap_lock);
  546. if (devmap->device != device) {
  547. spin_unlock(&dasd_devmap_lock);
  548. dasd_put_device(device);
  549. return;
  550. }
  551. devmap->device = NULL;
  552. spin_unlock(&dasd_devmap_lock);
  553. /* Disconnect dasd_device structure from ccw_device structure. */
  554. spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
  555. dev_set_drvdata(&device->cdev->dev, NULL);
  556. spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
  557. /*
  558. * Drop ref_count by 3, one for the devmap reference, one for
  559. * the cdev reference and one for the passed reference.
  560. */
  561. atomic_sub(3, &device->ref_count);
  562. /* Wait for reference counter to drop to zero. */
  563. wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
  564. /* Disconnect dasd_device structure from ccw_device structure. */
  565. cdev = device->cdev;
  566. device->cdev = NULL;
  567. /* Put ccw_device structure. */
  568. put_device(&cdev->dev);
  569. /* Now the device structure can be freed. */
  570. dasd_free_device(device);
  571. }
  572. /*
  573. * Reference counter dropped to zero. Wake up waiter
  574. * in dasd_delete_device.
  575. */
  576. void
  577. dasd_put_device_wake(struct dasd_device *device)
  578. {
  579. wake_up(&dasd_delete_wq);
  580. }
  581. EXPORT_SYMBOL_GPL(dasd_put_device_wake);
  582. /*
  583. * Return dasd_device structure associated with cdev.
  584. * This function needs to be called with the ccw device
  585. * lock held. It can be used from interrupt context.
  586. */
  587. struct dasd_device *
  588. dasd_device_from_cdev_locked(struct ccw_device *cdev)
  589. {
  590. struct dasd_device *device = dev_get_drvdata(&cdev->dev);
  591. if (!device)
  592. return ERR_PTR(-ENODEV);
  593. dasd_get_device(device);
  594. return device;
  595. }
  596. /*
  597. * Return dasd_device structure associated with cdev.
  598. */
  599. struct dasd_device *
  600. dasd_device_from_cdev(struct ccw_device *cdev)
  601. {
  602. struct dasd_device *device;
  603. unsigned long flags;
  604. spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
  605. device = dasd_device_from_cdev_locked(cdev);
  606. spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
  607. return device;
  608. }
  609. void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device)
  610. {
  611. struct dasd_devmap *devmap;
  612. devmap = dasd_find_busid(dev_name(&device->cdev->dev));
  613. if (IS_ERR(devmap))
  614. return;
  615. spin_lock(&dasd_devmap_lock);
  616. gdp->private_data = devmap;
  617. spin_unlock(&dasd_devmap_lock);
  618. }
  619. struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp)
  620. {
  621. struct dasd_device *device;
  622. struct dasd_devmap *devmap;
  623. if (!gdp->private_data)
  624. return NULL;
  625. device = NULL;
  626. spin_lock(&dasd_devmap_lock);
  627. devmap = gdp->private_data;
  628. if (devmap && devmap->device) {
  629. device = devmap->device;
  630. dasd_get_device(device);
  631. }
  632. spin_unlock(&dasd_devmap_lock);
  633. return device;
  634. }
  635. /*
  636. * SECTION: files in sysfs
  637. */
  638. /*
  639. * failfast controls the behaviour, if no path is available
  640. */
  641. static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
  642. char *buf)
  643. {
  644. struct dasd_devmap *devmap;
  645. int ff_flag;
  646. devmap = dasd_find_busid(dev_name(dev));
  647. if (!IS_ERR(devmap))
  648. ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
  649. else
  650. ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
  651. return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
  652. }
  653. static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
  654. const char *buf, size_t count)
  655. {
  656. struct dasd_devmap *devmap;
  657. int val;
  658. char *endp;
  659. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  660. if (IS_ERR(devmap))
  661. return PTR_ERR(devmap);
  662. val = simple_strtoul(buf, &endp, 0);
  663. if (((endp + 1) < (buf + count)) || (val > 1))
  664. return -EINVAL;
  665. spin_lock(&dasd_devmap_lock);
  666. if (val)
  667. devmap->features |= DASD_FEATURE_FAILFAST;
  668. else
  669. devmap->features &= ~DASD_FEATURE_FAILFAST;
  670. if (devmap->device)
  671. devmap->device->features = devmap->features;
  672. spin_unlock(&dasd_devmap_lock);
  673. return count;
  674. }
  675. static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
  676. /*
  677. * readonly controls the readonly status of a dasd
  678. */
  679. static ssize_t
  680. dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
  681. {
  682. struct dasd_devmap *devmap;
  683. int ro_flag;
  684. devmap = dasd_find_busid(dev_name(dev));
  685. if (!IS_ERR(devmap))
  686. ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
  687. else
  688. ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0;
  689. return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
  690. }
  691. static ssize_t
  692. dasd_ro_store(struct device *dev, struct device_attribute *attr,
  693. const char *buf, size_t count)
  694. {
  695. struct dasd_devmap *devmap;
  696. struct dasd_device *device;
  697. int val;
  698. char *endp;
  699. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  700. if (IS_ERR(devmap))
  701. return PTR_ERR(devmap);
  702. val = simple_strtoul(buf, &endp, 0);
  703. if (((endp + 1) < (buf + count)) || (val > 1))
  704. return -EINVAL;
  705. spin_lock(&dasd_devmap_lock);
  706. if (val)
  707. devmap->features |= DASD_FEATURE_READONLY;
  708. else
  709. devmap->features &= ~DASD_FEATURE_READONLY;
  710. device = devmap->device;
  711. if (device) {
  712. device->features = devmap->features;
  713. val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
  714. }
  715. spin_unlock(&dasd_devmap_lock);
  716. if (device && device->block && device->block->gdp)
  717. set_disk_ro(device->block->gdp, val);
  718. return count;
  719. }
  720. static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
  721. /*
  722. * erplog controls the logging of ERP related data
  723. * (e.g. failing channel programs).
  724. */
  725. static ssize_t
  726. dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
  727. {
  728. struct dasd_devmap *devmap;
  729. int erplog;
  730. devmap = dasd_find_busid(dev_name(dev));
  731. if (!IS_ERR(devmap))
  732. erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
  733. else
  734. erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0;
  735. return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n");
  736. }
  737. static ssize_t
  738. dasd_erplog_store(struct device *dev, struct device_attribute *attr,
  739. const char *buf, size_t count)
  740. {
  741. struct dasd_devmap *devmap;
  742. int val;
  743. char *endp;
  744. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  745. if (IS_ERR(devmap))
  746. return PTR_ERR(devmap);
  747. val = simple_strtoul(buf, &endp, 0);
  748. if (((endp + 1) < (buf + count)) || (val > 1))
  749. return -EINVAL;
  750. spin_lock(&dasd_devmap_lock);
  751. if (val)
  752. devmap->features |= DASD_FEATURE_ERPLOG;
  753. else
  754. devmap->features &= ~DASD_FEATURE_ERPLOG;
  755. if (devmap->device)
  756. devmap->device->features = devmap->features;
  757. spin_unlock(&dasd_devmap_lock);
  758. return count;
  759. }
  760. static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store);
  761. /*
  762. * use_diag controls whether the driver should use diag rather than ssch
  763. * to talk to the device
  764. */
  765. static ssize_t
  766. dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
  767. {
  768. struct dasd_devmap *devmap;
  769. int use_diag;
  770. devmap = dasd_find_busid(dev_name(dev));
  771. if (!IS_ERR(devmap))
  772. use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
  773. else
  774. use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
  775. return sprintf(buf, use_diag ? "1\n" : "0\n");
  776. }
  777. static ssize_t
  778. dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
  779. const char *buf, size_t count)
  780. {
  781. struct dasd_devmap *devmap;
  782. ssize_t rc;
  783. int val;
  784. char *endp;
  785. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  786. if (IS_ERR(devmap))
  787. return PTR_ERR(devmap);
  788. val = simple_strtoul(buf, &endp, 0);
  789. if (((endp + 1) < (buf + count)) || (val > 1))
  790. return -EINVAL;
  791. spin_lock(&dasd_devmap_lock);
  792. /* Changing diag discipline flag is only allowed in offline state. */
  793. rc = count;
  794. if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
  795. if (val)
  796. devmap->features |= DASD_FEATURE_USEDIAG;
  797. else
  798. devmap->features &= ~DASD_FEATURE_USEDIAG;
  799. } else
  800. rc = -EPERM;
  801. spin_unlock(&dasd_devmap_lock);
  802. return rc;
  803. }
  804. static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
  805. /*
  806. * use_raw controls whether the driver should give access to raw eckd data or
  807. * operate in standard mode
  808. */
  809. static ssize_t
  810. dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
  811. {
  812. struct dasd_devmap *devmap;
  813. int use_raw;
  814. devmap = dasd_find_busid(dev_name(dev));
  815. if (!IS_ERR(devmap))
  816. use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
  817. else
  818. use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
  819. return sprintf(buf, use_raw ? "1\n" : "0\n");
  820. }
  821. static ssize_t
  822. dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
  823. const char *buf, size_t count)
  824. {
  825. struct dasd_devmap *devmap;
  826. ssize_t rc;
  827. unsigned long val;
  828. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  829. if (IS_ERR(devmap))
  830. return PTR_ERR(devmap);
  831. if ((strict_strtoul(buf, 10, &val) != 0) || val > 1)
  832. return -EINVAL;
  833. spin_lock(&dasd_devmap_lock);
  834. /* Changing diag discipline flag is only allowed in offline state. */
  835. rc = count;
  836. if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
  837. if (val)
  838. devmap->features |= DASD_FEATURE_USERAW;
  839. else
  840. devmap->features &= ~DASD_FEATURE_USERAW;
  841. } else
  842. rc = -EPERM;
  843. spin_unlock(&dasd_devmap_lock);
  844. return rc;
  845. }
  846. static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
  847. dasd_use_raw_store);
  848. static ssize_t
  849. dasd_discipline_show(struct device *dev, struct device_attribute *attr,
  850. char *buf)
  851. {
  852. struct dasd_device *device;
  853. ssize_t len;
  854. device = dasd_device_from_cdev(to_ccwdev(dev));
  855. if (IS_ERR(device))
  856. goto out;
  857. else if (!device->discipline) {
  858. dasd_put_device(device);
  859. goto out;
  860. } else {
  861. len = snprintf(buf, PAGE_SIZE, "%s\n",
  862. device->discipline->name);
  863. dasd_put_device(device);
  864. return len;
  865. }
  866. out:
  867. len = snprintf(buf, PAGE_SIZE, "none\n");
  868. return len;
  869. }
  870. static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
  871. static ssize_t
  872. dasd_device_status_show(struct device *dev, struct device_attribute *attr,
  873. char *buf)
  874. {
  875. struct dasd_device *device;
  876. ssize_t len;
  877. device = dasd_device_from_cdev(to_ccwdev(dev));
  878. if (!IS_ERR(device)) {
  879. switch (device->state) {
  880. case DASD_STATE_NEW:
  881. len = snprintf(buf, PAGE_SIZE, "new\n");
  882. break;
  883. case DASD_STATE_KNOWN:
  884. len = snprintf(buf, PAGE_SIZE, "detected\n");
  885. break;
  886. case DASD_STATE_BASIC:
  887. len = snprintf(buf, PAGE_SIZE, "basic\n");
  888. break;
  889. case DASD_STATE_UNFMT:
  890. len = snprintf(buf, PAGE_SIZE, "unformatted\n");
  891. break;
  892. case DASD_STATE_READY:
  893. len = snprintf(buf, PAGE_SIZE, "ready\n");
  894. break;
  895. case DASD_STATE_ONLINE:
  896. len = snprintf(buf, PAGE_SIZE, "online\n");
  897. break;
  898. default:
  899. len = snprintf(buf, PAGE_SIZE, "no stat\n");
  900. break;
  901. }
  902. dasd_put_device(device);
  903. } else
  904. len = snprintf(buf, PAGE_SIZE, "unknown\n");
  905. return len;
  906. }
  907. static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
  908. static ssize_t dasd_alias_show(struct device *dev,
  909. struct device_attribute *attr, char *buf)
  910. {
  911. struct dasd_device *device;
  912. struct dasd_uid uid;
  913. device = dasd_device_from_cdev(to_ccwdev(dev));
  914. if (IS_ERR(device))
  915. return sprintf(buf, "0\n");
  916. if (device->discipline && device->discipline->get_uid &&
  917. !device->discipline->get_uid(device, &uid)) {
  918. if (uid.type == UA_BASE_PAV_ALIAS ||
  919. uid.type == UA_HYPER_PAV_ALIAS) {
  920. dasd_put_device(device);
  921. return sprintf(buf, "1\n");
  922. }
  923. }
  924. dasd_put_device(device);
  925. return sprintf(buf, "0\n");
  926. }
  927. static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
  928. static ssize_t dasd_vendor_show(struct device *dev,
  929. struct device_attribute *attr, char *buf)
  930. {
  931. struct dasd_device *device;
  932. struct dasd_uid uid;
  933. char *vendor;
  934. device = dasd_device_from_cdev(to_ccwdev(dev));
  935. vendor = "";
  936. if (IS_ERR(device))
  937. return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
  938. if (device->discipline && device->discipline->get_uid &&
  939. !device->discipline->get_uid(device, &uid))
  940. vendor = uid.vendor;
  941. dasd_put_device(device);
  942. return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
  943. }
  944. static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
  945. #define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\
  946. /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 +\
  947. /* vduit */ 32 + 1)
  948. static ssize_t
  949. dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
  950. {
  951. struct dasd_device *device;
  952. struct dasd_uid uid;
  953. char uid_string[UID_STRLEN];
  954. char ua_string[3];
  955. device = dasd_device_from_cdev(to_ccwdev(dev));
  956. uid_string[0] = 0;
  957. if (IS_ERR(device))
  958. return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
  959. if (device->discipline && device->discipline->get_uid &&
  960. !device->discipline->get_uid(device, &uid)) {
  961. switch (uid.type) {
  962. case UA_BASE_DEVICE:
  963. snprintf(ua_string, sizeof(ua_string), "%02x",
  964. uid.real_unit_addr);
  965. break;
  966. case UA_BASE_PAV_ALIAS:
  967. snprintf(ua_string, sizeof(ua_string), "%02x",
  968. uid.base_unit_addr);
  969. break;
  970. case UA_HYPER_PAV_ALIAS:
  971. snprintf(ua_string, sizeof(ua_string), "xx");
  972. break;
  973. default:
  974. /* should not happen, treat like base device */
  975. snprintf(ua_string, sizeof(ua_string), "%02x",
  976. uid.real_unit_addr);
  977. break;
  978. }
  979. if (strlen(uid.vduit) > 0)
  980. snprintf(uid_string, sizeof(uid_string),
  981. "%s.%s.%04x.%s.%s",
  982. uid.vendor, uid.serial, uid.ssid, ua_string,
  983. uid.vduit);
  984. else
  985. snprintf(uid_string, sizeof(uid_string),
  986. "%s.%s.%04x.%s",
  987. uid.vendor, uid.serial, uid.ssid, ua_string);
  988. }
  989. dasd_put_device(device);
  990. return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
  991. }
  992. static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
  993. /*
  994. * extended error-reporting
  995. */
  996. static ssize_t
  997. dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
  998. {
  999. struct dasd_devmap *devmap;
  1000. int eer_flag;
  1001. devmap = dasd_find_busid(dev_name(dev));
  1002. if (!IS_ERR(devmap) && devmap->device)
  1003. eer_flag = dasd_eer_enabled(devmap->device);
  1004. else
  1005. eer_flag = 0;
  1006. return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
  1007. }
  1008. static ssize_t
  1009. dasd_eer_store(struct device *dev, struct device_attribute *attr,
  1010. const char *buf, size_t count)
  1011. {
  1012. struct dasd_devmap *devmap;
  1013. int val, rc;
  1014. char *endp;
  1015. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  1016. if (IS_ERR(devmap))
  1017. return PTR_ERR(devmap);
  1018. if (!devmap->device)
  1019. return -ENODEV;
  1020. val = simple_strtoul(buf, &endp, 0);
  1021. if (((endp + 1) < (buf + count)) || (val > 1))
  1022. return -EINVAL;
  1023. if (val) {
  1024. rc = dasd_eer_enable(devmap->device);
  1025. if (rc)
  1026. return rc;
  1027. } else
  1028. dasd_eer_disable(devmap->device);
  1029. return count;
  1030. }
  1031. static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
  1032. /*
  1033. * expiration time for default requests
  1034. */
  1035. static ssize_t
  1036. dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf)
  1037. {
  1038. struct dasd_device *device;
  1039. int len;
  1040. device = dasd_device_from_cdev(to_ccwdev(dev));
  1041. if (IS_ERR(device))
  1042. return -ENODEV;
  1043. len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires);
  1044. dasd_put_device(device);
  1045. return len;
  1046. }
  1047. static ssize_t
  1048. dasd_expires_store(struct device *dev, struct device_attribute *attr,
  1049. const char *buf, size_t count)
  1050. {
  1051. struct dasd_device *device;
  1052. unsigned long val;
  1053. device = dasd_device_from_cdev(to_ccwdev(dev));
  1054. if (IS_ERR(device))
  1055. return -ENODEV;
  1056. if ((strict_strtoul(buf, 10, &val) != 0) ||
  1057. (val > DASD_EXPIRES_MAX) || val == 0) {
  1058. dasd_put_device(device);
  1059. return -EINVAL;
  1060. }
  1061. if (val)
  1062. device->default_expires = val;
  1063. dasd_put_device(device);
  1064. return count;
  1065. }
  1066. static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
  1067. static ssize_t dasd_reservation_policy_show(struct device *dev,
  1068. struct device_attribute *attr,
  1069. char *buf)
  1070. {
  1071. struct dasd_devmap *devmap;
  1072. int rc = 0;
  1073. devmap = dasd_find_busid(dev_name(dev));
  1074. if (IS_ERR(devmap)) {
  1075. rc = snprintf(buf, PAGE_SIZE, "ignore\n");
  1076. } else {
  1077. spin_lock(&dasd_devmap_lock);
  1078. if (devmap->features & DASD_FEATURE_FAILONSLCK)
  1079. rc = snprintf(buf, PAGE_SIZE, "fail\n");
  1080. else
  1081. rc = snprintf(buf, PAGE_SIZE, "ignore\n");
  1082. spin_unlock(&dasd_devmap_lock);
  1083. }
  1084. return rc;
  1085. }
  1086. static ssize_t dasd_reservation_policy_store(struct device *dev,
  1087. struct device_attribute *attr,
  1088. const char *buf, size_t count)
  1089. {
  1090. struct dasd_devmap *devmap;
  1091. int rc;
  1092. devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
  1093. if (IS_ERR(devmap))
  1094. return PTR_ERR(devmap);
  1095. rc = 0;
  1096. spin_lock(&dasd_devmap_lock);
  1097. if (sysfs_streq("ignore", buf))
  1098. devmap->features &= ~DASD_FEATURE_FAILONSLCK;
  1099. else if (sysfs_streq("fail", buf))
  1100. devmap->features |= DASD_FEATURE_FAILONSLCK;
  1101. else
  1102. rc = -EINVAL;
  1103. if (devmap->device)
  1104. devmap->device->features = devmap->features;
  1105. spin_unlock(&dasd_devmap_lock);
  1106. if (rc)
  1107. return rc;
  1108. else
  1109. return count;
  1110. }
  1111. static DEVICE_ATTR(reservation_policy, 0644,
  1112. dasd_reservation_policy_show, dasd_reservation_policy_store);
  1113. static ssize_t dasd_reservation_state_show(struct device *dev,
  1114. struct device_attribute *attr,
  1115. char *buf)
  1116. {
  1117. struct dasd_device *device;
  1118. int rc = 0;
  1119. device = dasd_device_from_cdev(to_ccwdev(dev));
  1120. if (IS_ERR(device))
  1121. return snprintf(buf, PAGE_SIZE, "none\n");
  1122. if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
  1123. rc = snprintf(buf, PAGE_SIZE, "reserved\n");
  1124. else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
  1125. rc = snprintf(buf, PAGE_SIZE, "lost\n");
  1126. else
  1127. rc = snprintf(buf, PAGE_SIZE, "none\n");
  1128. dasd_put_device(device);
  1129. return rc;
  1130. }
  1131. static ssize_t dasd_reservation_state_store(struct device *dev,
  1132. struct device_attribute *attr,
  1133. const char *buf, size_t count)
  1134. {
  1135. struct dasd_device *device;
  1136. int rc = 0;
  1137. device = dasd_device_from_cdev(to_ccwdev(dev));
  1138. if (IS_ERR(device))
  1139. return -ENODEV;
  1140. if (sysfs_streq("reset", buf))
  1141. clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
  1142. else
  1143. rc = -EINVAL;
  1144. dasd_put_device(device);
  1145. if (rc)
  1146. return rc;
  1147. else
  1148. return count;
  1149. }
  1150. static DEVICE_ATTR(last_known_reservation_state, 0644,
  1151. dasd_reservation_state_show, dasd_reservation_state_store);
  1152. static struct attribute * dasd_attrs[] = {
  1153. &dev_attr_readonly.attr,
  1154. &dev_attr_discipline.attr,
  1155. &dev_attr_status.attr,
  1156. &dev_attr_alias.attr,
  1157. &dev_attr_vendor.attr,
  1158. &dev_attr_uid.attr,
  1159. &dev_attr_use_diag.attr,
  1160. &dev_attr_raw_track_access.attr,
  1161. &dev_attr_eer_enabled.attr,
  1162. &dev_attr_erplog.attr,
  1163. &dev_attr_failfast.attr,
  1164. &dev_attr_expires.attr,
  1165. &dev_attr_reservation_policy.attr,
  1166. &dev_attr_last_known_reservation_state.attr,
  1167. NULL,
  1168. };
  1169. static struct attribute_group dasd_attr_group = {
  1170. .attrs = dasd_attrs,
  1171. };
  1172. /*
  1173. * Return value of the specified feature.
  1174. */
  1175. int
  1176. dasd_get_feature(struct ccw_device *cdev, int feature)
  1177. {
  1178. struct dasd_devmap *devmap;
  1179. devmap = dasd_find_busid(dev_name(&cdev->dev));
  1180. if (IS_ERR(devmap))
  1181. return PTR_ERR(devmap);
  1182. return ((devmap->features & feature) != 0);
  1183. }
  1184. /*
  1185. * Set / reset given feature.
  1186. * Flag indicates wether to set (!=0) or the reset (=0) the feature.
  1187. */
  1188. int
  1189. dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
  1190. {
  1191. struct dasd_devmap *devmap;
  1192. devmap = dasd_find_busid(dev_name(&cdev->dev));
  1193. if (IS_ERR(devmap))
  1194. return PTR_ERR(devmap);
  1195. spin_lock(&dasd_devmap_lock);
  1196. if (flag)
  1197. devmap->features |= feature;
  1198. else
  1199. devmap->features &= ~feature;
  1200. if (devmap->device)
  1201. devmap->device->features = devmap->features;
  1202. spin_unlock(&dasd_devmap_lock);
  1203. return 0;
  1204. }
  1205. int
  1206. dasd_add_sysfs_files(struct ccw_device *cdev)
  1207. {
  1208. return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
  1209. }
  1210. void
  1211. dasd_remove_sysfs_files(struct ccw_device *cdev)
  1212. {
  1213. sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
  1214. }
  1215. int
  1216. dasd_devmap_init(void)
  1217. {
  1218. int i;
  1219. /* Initialize devmap structures. */
  1220. dasd_max_devindex = 0;
  1221. for (i = 0; i < 256; i++)
  1222. INIT_LIST_HEAD(&dasd_hashlists[i]);
  1223. return 0;
  1224. }
  1225. void
  1226. dasd_devmap_exit(void)
  1227. {
  1228. dasd_forget_ranges();
  1229. }