hpwdt.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. /*
  2. * HP WatchDog Driver
  3. * based on
  4. *
  5. * SoftDog 0.05: A Software Watchdog Device
  6. *
  7. * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
  8. * Thomas Mingarelli <thomas.mingarelli@hp.com>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * version 2 as published by the Free Software Foundation
  13. *
  14. */
  15. #include <linux/device.h>
  16. #include <linux/fs.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/io.h>
  20. #include <linux/irq.h>
  21. #include <linux/kernel.h>
  22. #include <linux/miscdevice.h>
  23. #include <linux/mm.h>
  24. #include <linux/module.h>
  25. #include <linux/kdebug.h>
  26. #include <linux/moduleparam.h>
  27. #include <linux/notifier.h>
  28. #include <linux/pci.h>
  29. #include <linux/pci_ids.h>
  30. #include <linux/reboot.h>
  31. #include <linux/sched.h>
  32. #include <linux/timer.h>
  33. #include <linux/types.h>
  34. #include <linux/uaccess.h>
  35. #include <linux/watchdog.h>
  36. #include <linux/dmi.h>
  37. #include <linux/efi.h>
  38. #include <linux/string.h>
  39. #include <linux/bootmem.h>
  40. #include <linux/slab.h>
  41. #include <asm/dmi.h>
  42. #include <asm/desc.h>
  43. #include <asm/kdebug.h>
  44. #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */
  45. #define CRU_BIOS_SIGNATURE_VALUE 0x55524324
  46. #define PCI_BIOS32_PARAGRAPH_LEN 16
  47. #define PCI_ROM_BASE1 0x000F0000
  48. #define ROM_SIZE 0x10000
  49. struct bios32_service_dir {
  50. u32 signature;
  51. u32 entry_point;
  52. u8 revision;
  53. u8 length;
  54. u8 checksum;
  55. u8 reserved[5];
  56. };
  57. /*
  58. * smbios_entry_point - defines SMBIOS entry point structure
  59. *
  60. * anchor[4] - anchor string (_SM_)
  61. * checksum - checksum of the entry point structure
  62. * length - length of the entry point structure
  63. * major_ver - major version (02h for revision 2.1)
  64. * minor_ver - minor version (01h for revision 2.1)
  65. * max_struct_size - size of the largest SMBIOS structure
  66. * revision - entry point structure revision implemented
  67. * formatted_area[5] - reserved
  68. * intermediate_anchor[5] - intermediate anchor string (_DMI_)
  69. * intermediate_checksum - intermediate checksum
  70. * table_length - structure table length
  71. * table_address - structure table address
  72. * table_num_structs - number of SMBIOS structures present
  73. * bcd_revision - BCD revision
  74. */
  75. struct smbios_entry_point {
  76. u8 anchor[4];
  77. u8 checksum;
  78. u8 length;
  79. u8 major_ver;
  80. u8 minor_ver;
  81. u16 max_struct_size;
  82. u8 revision;
  83. u8 formatted_area[5];
  84. u8 intermediate_anchor[5];
  85. u8 intermediate_checksum;
  86. u16 table_length;
  87. u32 table_address;
  88. u16 table_num_structs;
  89. u8 bcd_revision;
  90. };
  91. /* type 212 */
  92. struct smbios_cru64_info {
  93. u8 type;
  94. u8 byte_length;
  95. u16 handle;
  96. u32 signature;
  97. u64 physical_address;
  98. u32 double_length;
  99. u32 double_offset;
  100. };
  101. #define SMBIOS_CRU64_INFORMATION 212
  102. struct cmn_registers {
  103. union {
  104. struct {
  105. u8 ral;
  106. u8 rah;
  107. u16 rea2;
  108. };
  109. u32 reax;
  110. } u1;
  111. union {
  112. struct {
  113. u8 rbl;
  114. u8 rbh;
  115. u8 reb2l;
  116. u8 reb2h;
  117. };
  118. u32 rebx;
  119. } u2;
  120. union {
  121. struct {
  122. u8 rcl;
  123. u8 rch;
  124. u16 rec2;
  125. };
  126. u32 recx;
  127. } u3;
  128. union {
  129. struct {
  130. u8 rdl;
  131. u8 rdh;
  132. u16 red2;
  133. };
  134. u32 redx;
  135. } u4;
  136. u32 resi;
  137. u32 redi;
  138. u16 rds;
  139. u16 res;
  140. u32 reflags;
  141. } __attribute__((packed));
  142. #define DEFAULT_MARGIN 30
  143. static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */
  144. static unsigned int reload; /* the computed soft_margin */
  145. static int nowayout = WATCHDOG_NOWAYOUT;
  146. static char expect_release;
  147. static unsigned long hpwdt_is_open;
  148. static void __iomem *pci_mem_addr; /* the PCI-memory address */
  149. static unsigned long __iomem *hpwdt_timer_reg;
  150. static unsigned long __iomem *hpwdt_timer_con;
  151. static DEFINE_SPINLOCK(rom_lock);
  152. static void *cru_rom_addr;
  153. static struct cmn_registers cmn_regs;
  154. static struct pci_device_id hpwdt_devices[] = {
  155. {
  156. .vendor = PCI_VENDOR_ID_COMPAQ,
  157. .device = 0xB203,
  158. .subvendor = PCI_ANY_ID,
  159. .subdevice = PCI_ANY_ID,
  160. },
  161. {0}, /* terminate list */
  162. };
  163. MODULE_DEVICE_TABLE(pci, hpwdt_devices);
  164. /*
  165. * bios_checksum
  166. */
  167. static int __devinit bios_checksum(const char __iomem *ptr, int len)
  168. {
  169. char sum = 0;
  170. int i;
  171. /*
  172. * calculate checksum of size bytes. This should add up
  173. * to zero if we have a valid header.
  174. */
  175. for (i = 0; i < len; i++)
  176. sum += ptr[i];
  177. return ((sum == 0) && (len > 0));
  178. }
  179. #ifndef CONFIG_X86_64
  180. /* --32 Bit Bios------------------------------------------------------------ */
  181. #define HPWDT_ARCH 32
  182. asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
  183. unsigned long *pRomEntry)
  184. {
  185. asm("pushl %ebp \n\t"
  186. "movl %esp, %ebp \n\t"
  187. "pusha \n\t"
  188. "pushf \n\t"
  189. "push %es \n\t"
  190. "push %ds \n\t"
  191. "pop %es \n\t"
  192. "movl 8(%ebp),%eax \n\t"
  193. "movl 4(%eax),%ebx \n\t"
  194. "movl 8(%eax),%ecx \n\t"
  195. "movl 12(%eax),%edx \n\t"
  196. "movl 16(%eax),%esi \n\t"
  197. "movl 20(%eax),%edi \n\t"
  198. "movl (%eax),%eax \n\t"
  199. "push %cs \n\t"
  200. "call *12(%ebp) \n\t"
  201. "pushf \n\t"
  202. "pushl %eax \n\t"
  203. "movl 8(%ebp),%eax \n\t"
  204. "movl %ebx,4(%eax) \n\t"
  205. "movl %ecx,8(%eax) \n\t"
  206. "movl %edx,12(%eax) \n\t"
  207. "movl %esi,16(%eax) \n\t"
  208. "movl %edi,20(%eax) \n\t"
  209. "movw %ds,24(%eax) \n\t"
  210. "movw %es,26(%eax) \n\t"
  211. "popl %ebx \n\t"
  212. "movl %ebx,(%eax) \n\t"
  213. "popl %ebx \n\t"
  214. "movl %ebx,28(%eax) \n\t"
  215. "pop %es \n\t"
  216. "popf \n\t"
  217. "popa \n\t"
  218. "leave \n\t" "ret");
  219. }
  220. /*
  221. * cru_detect
  222. *
  223. * Routine Description:
  224. * This function uses the 32-bit BIOS Service Directory record to
  225. * search for a $CRU record.
  226. *
  227. * Return Value:
  228. * 0 : SUCCESS
  229. * <0 : FAILURE
  230. */
  231. static int __devinit cru_detect(unsigned long map_entry,
  232. unsigned long map_offset)
  233. {
  234. void *bios32_map;
  235. unsigned long *bios32_entrypoint;
  236. unsigned long cru_physical_address;
  237. unsigned long cru_length;
  238. unsigned long physical_bios_base = 0;
  239. unsigned long physical_bios_offset = 0;
  240. int retval = -ENODEV;
  241. bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));
  242. if (bios32_map == NULL)
  243. return -ENODEV;
  244. bios32_entrypoint = bios32_map + map_offset;
  245. cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
  246. asminline_call(&cmn_regs, bios32_entrypoint);
  247. if (cmn_regs.u1.ral != 0) {
  248. printk(KERN_WARNING
  249. "hpwdt: Call succeeded but with an error: 0x%x\n",
  250. cmn_regs.u1.ral);
  251. } else {
  252. physical_bios_base = cmn_regs.u2.rebx;
  253. physical_bios_offset = cmn_regs.u4.redx;
  254. cru_length = cmn_regs.u3.recx;
  255. cru_physical_address =
  256. physical_bios_base + physical_bios_offset;
  257. /* If the values look OK, then map it in. */
  258. if ((physical_bios_base + physical_bios_offset)) {
  259. cru_rom_addr =
  260. ioremap(cru_physical_address, cru_length);
  261. if (cru_rom_addr)
  262. retval = 0;
  263. }
  264. printk(KERN_DEBUG "hpwdt: CRU Base Address: 0x%lx\n",
  265. physical_bios_base);
  266. printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n",
  267. physical_bios_offset);
  268. printk(KERN_DEBUG "hpwdt: CRU Length: 0x%lx\n",
  269. cru_length);
  270. printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n",
  271. (unsigned int)&cru_rom_addr);
  272. }
  273. iounmap(bios32_map);
  274. return retval;
  275. }
  276. /*
  277. * bios32_present
  278. *
  279. * Routine Description:
  280. * This function finds the 32-bit BIOS Service Directory
  281. *
  282. * Return Value:
  283. * 0 : SUCCESS
  284. * <0 : FAILURE
  285. */
  286. static int __devinit bios32_present(const char __iomem *p)
  287. {
  288. struct bios32_service_dir *bios_32_ptr;
  289. int length;
  290. unsigned long map_entry, map_offset;
  291. bios_32_ptr = (struct bios32_service_dir *) p;
  292. /*
  293. * Search for signature by checking equal to the swizzled value
  294. * instead of calling another routine to perform a strcmp.
  295. */
  296. if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) {
  297. length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN;
  298. if (bios_checksum(p, length)) {
  299. /*
  300. * According to the spec, we're looking for the
  301. * first 4KB-aligned address below the entrypoint
  302. * listed in the header. The Service Directory code
  303. * is guaranteed to occupy no more than 2 4KB pages.
  304. */
  305. map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1);
  306. map_offset = bios_32_ptr->entry_point - map_entry;
  307. return cru_detect(map_entry, map_offset);
  308. }
  309. }
  310. return -ENODEV;
  311. }
  312. static int __devinit detect_cru_service(void)
  313. {
  314. char __iomem *p, *q;
  315. int rc = -1;
  316. /*
  317. * Search from 0x0f0000 through 0x0fffff, inclusive.
  318. */
  319. p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
  320. if (p == NULL)
  321. return -ENOMEM;
  322. for (q = p; q < p + ROM_SIZE; q += 16) {
  323. rc = bios32_present(q);
  324. if (!rc)
  325. break;
  326. }
  327. iounmap(p);
  328. return rc;
  329. }
  330. #else
  331. /* --64 Bit Bios------------------------------------------------------------ */
  332. #define HPWDT_ARCH 64
  333. asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
  334. unsigned long *pRomEntry)
  335. {
  336. asm("pushq %rbp \n\t"
  337. "movq %rsp, %rbp \n\t"
  338. "pushq %rax \n\t"
  339. "pushq %rbx \n\t"
  340. "pushq %rdx \n\t"
  341. "pushq %r12 \n\t"
  342. "pushq %r9 \n\t"
  343. "movq %rsi, %r12 \n\t"
  344. "movq %rdi, %r9 \n\t"
  345. "movl 4(%r9),%ebx \n\t"
  346. "movl 8(%r9),%ecx \n\t"
  347. "movl 12(%r9),%edx \n\t"
  348. "movl 16(%r9),%esi \n\t"
  349. "movl 20(%r9),%edi \n\t"
  350. "movl (%r9),%eax \n\t"
  351. "call *%r12 \n\t"
  352. "pushfq \n\t"
  353. "popq %r12 \n\t"
  354. "popfq \n\t"
  355. "movl %eax, (%r9) \n\t"
  356. "movl %ebx, 4(%r9) \n\t"
  357. "movl %ecx, 8(%r9) \n\t"
  358. "movl %edx, 12(%r9) \n\t"
  359. "movl %esi, 16(%r9) \n\t"
  360. "movl %edi, 20(%r9) \n\t"
  361. "movq %r12, %rax \n\t"
  362. "movl %eax, 28(%r9) \n\t"
  363. "popq %r9 \n\t"
  364. "popq %r12 \n\t"
  365. "popq %rdx \n\t"
  366. "popq %rbx \n\t"
  367. "popq %rax \n\t"
  368. "leave \n\t" "ret");
  369. }
  370. /*
  371. * dmi_find_cru
  372. *
  373. * Routine Description:
  374. * This function checks wether or not a SMBIOS/DMI record is
  375. * the 64bit CRU info or not
  376. *
  377. * Return Value:
  378. * 0 : SUCCESS - if record found
  379. * <0 : FAILURE - if record not found
  380. */
  381. static void __devinit dmi_find_cru(const struct dmi_header *dm)
  382. {
  383. struct smbios_cru64_info *smbios_cru64_ptr;
  384. unsigned long cru_physical_address;
  385. if (dm->type == SMBIOS_CRU64_INFORMATION) {
  386. smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
  387. if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
  388. cru_physical_address =
  389. smbios_cru64_ptr->physical_address +
  390. smbios_cru64_ptr->double_offset;
  391. cru_rom_addr = ioremap(cru_physical_address,
  392. smbios_cru64_ptr->double_length);
  393. }
  394. }
  395. }
  396. /*
  397. * dmi_table
  398. *
  399. * Routine Description:
  400. * Decode the SMBIOS/DMI table and check if we have a 64bit CRU record
  401. * or not.
  402. *
  403. * We have to be cautious here. We have seen BIOSes with DMI pointers
  404. * pointing to completely the wrong place for example
  405. */
  406. static void __devinit dmi_table(u8 *buf, int len, int num,
  407. void (*decode)(const struct dmi_header *))
  408. {
  409. u8 *data = buf;
  410. int i = 0;
  411. /*
  412. * Stop when we see all the items the table claimed to have
  413. * OR we run off the end of the table (also happens)
  414. */
  415. while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
  416. const struct dmi_header *dm = (const struct dmi_header *)data;
  417. /*
  418. * We want to know the total length (formated area and strings)
  419. * before decoding to make sure we won't run off the table in
  420. * dmi_decode or dmi_string
  421. */
  422. data += dm->length;
  423. while ((data - buf < len - 1) && (data[0] || data[1]))
  424. data++;
  425. if (data - buf < len - 1)
  426. decode(dm);
  427. data += 2;
  428. i++;
  429. }
  430. }
  431. /*
  432. * smbios_present
  433. *
  434. * Routine Description:
  435. * This function parses the SMBIOS entry point table to retrieve
  436. * the 64 bit CRU Service.
  437. *
  438. * Return Value:
  439. * 0 : SUCCESS
  440. * <0 : FAILURE
  441. */
  442. static int __devinit smbios_present(const char __iomem *p)
  443. {
  444. struct smbios_entry_point *eps =
  445. (struct smbios_entry_point *) p;
  446. int length;
  447. u8 *buf;
  448. /* check if we have indeed the SMBIOS table entry point */
  449. if ((strncmp((char *)eps->anchor, "_SM_",
  450. sizeof(eps->anchor))) == 0) {
  451. length = eps->length;
  452. /* SMBIOS v2.1 implementation might use 0x1e */
  453. if ((length == 0x1e) &&
  454. (eps->major_ver == 2) &&
  455. (eps->minor_ver == 1))
  456. length = 0x1f;
  457. /*
  458. * Now we will check:
  459. * - SMBIOS checksum must be 0
  460. * - intermediate anchor should be _DMI_
  461. * - intermediate checksum should be 0
  462. */
  463. if ((bios_checksum(p, length)) &&
  464. (strncmp((char *)eps->intermediate_anchor, "_DMI_",
  465. sizeof(eps->intermediate_anchor)) == 0) &&
  466. (bios_checksum(p+0x10, 15))) {
  467. buf = ioremap(eps->table_address, eps->table_length);
  468. if (buf == NULL)
  469. return -ENODEV;
  470. /* Scan the DMI table for the 64 bit CRU service */
  471. dmi_table(buf, eps->table_length,
  472. eps->table_num_structs, dmi_find_cru);
  473. iounmap(buf);
  474. return 0;
  475. }
  476. }
  477. return -ENODEV;
  478. }
  479. static int __devinit smbios_scan_machine(void)
  480. {
  481. char __iomem *p, *q;
  482. int rc;
  483. if (efi_enabled) {
  484. if (efi.smbios == EFI_INVALID_TABLE_ADDR)
  485. return -ENODEV;
  486. p = ioremap(efi.smbios, 32);
  487. if (p == NULL)
  488. return -ENOMEM;
  489. rc = smbios_present(p);
  490. iounmap(p);
  491. } else {
  492. /*
  493. * Search from 0x0f0000 through 0x0fffff, inclusive.
  494. */
  495. p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
  496. if (p == NULL)
  497. return -ENOMEM;
  498. for (q = p; q < p + ROM_SIZE; q += 16) {
  499. rc = smbios_present(q);
  500. if (!rc) {
  501. break;
  502. }
  503. }
  504. iounmap(p);
  505. }
  506. }
  507. static int __devinit detect_cru_service(void)
  508. {
  509. cru_rom_addr = NULL;
  510. smbios_scan_machine(); /* will become dmi_walk(dmi_find_cru); */
  511. /* if cru_rom_addr has been set then we found a CRU service */
  512. return ((cru_rom_addr != NULL)? 0: -ENODEV);
  513. }
  514. /* ------------------------------------------------------------------------- */
  515. #endif
  516. /*
  517. * NMI Handler
  518. */
  519. static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
  520. void *data)
  521. {
  522. static unsigned long rom_pl;
  523. static int die_nmi_called;
  524. if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
  525. return NOTIFY_OK;
  526. spin_lock_irqsave(&rom_lock, rom_pl);
  527. if (!die_nmi_called)
  528. asminline_call(&cmn_regs, cru_rom_addr);
  529. die_nmi_called = 1;
  530. spin_unlock_irqrestore(&rom_lock, rom_pl);
  531. if (cmn_regs.u1.ral == 0) {
  532. printk(KERN_WARNING "hpwdt: An NMI occurred, "
  533. "but unable to determine source.\n");
  534. } else {
  535. panic("An NMI occurred, please see the Integrated "
  536. "Management Log for details.\n");
  537. }
  538. return NOTIFY_STOP;
  539. }
  540. /*
  541. * Watchdog operations
  542. */
  543. static void hpwdt_start(void)
  544. {
  545. reload = (soft_margin * 1000) / 128;
  546. iowrite16(reload, hpwdt_timer_reg);
  547. iowrite16(0x85, hpwdt_timer_con);
  548. }
  549. static void hpwdt_stop(void)
  550. {
  551. unsigned long data;
  552. data = ioread16(hpwdt_timer_con);
  553. data &= 0xFE;
  554. iowrite16(data, hpwdt_timer_con);
  555. }
  556. static void hpwdt_ping(void)
  557. {
  558. iowrite16(reload, hpwdt_timer_reg);
  559. }
  560. static int hpwdt_change_timer(int new_margin)
  561. {
  562. /* Arbitrary, can't find the card's limits */
  563. if (new_margin < 30 || new_margin > 600) {
  564. printk(KERN_WARNING
  565. "hpwdt: New value passed in is invalid: %d seconds.\n",
  566. new_margin);
  567. return -EINVAL;
  568. }
  569. soft_margin = new_margin;
  570. printk(KERN_DEBUG
  571. "hpwdt: New timer passed in is %d seconds.\n",
  572. new_margin);
  573. reload = (soft_margin * 1000) / 128;
  574. return 0;
  575. }
  576. /*
  577. * /dev/watchdog handling
  578. */
  579. static int hpwdt_open(struct inode *inode, struct file *file)
  580. {
  581. /* /dev/watchdog can only be opened once */
  582. if (test_and_set_bit(0, &hpwdt_is_open))
  583. return -EBUSY;
  584. /* Start the watchdog */
  585. hpwdt_start();
  586. hpwdt_ping();
  587. return nonseekable_open(inode, file);
  588. }
  589. static int hpwdt_release(struct inode *inode, struct file *file)
  590. {
  591. /* Stop the watchdog */
  592. if (expect_release == 42) {
  593. hpwdt_stop();
  594. } else {
  595. printk(KERN_CRIT
  596. "hpwdt: Unexpected close, not stopping watchdog!\n");
  597. hpwdt_ping();
  598. }
  599. expect_release = 0;
  600. /* /dev/watchdog is being closed, make sure it can be re-opened */
  601. clear_bit(0, &hpwdt_is_open);
  602. return 0;
  603. }
  604. static ssize_t hpwdt_write(struct file *file, const char __user *data,
  605. size_t len, loff_t *ppos)
  606. {
  607. /* See if we got the magic character 'V' and reload the timer */
  608. if (len) {
  609. if (!nowayout) {
  610. size_t i;
  611. /* note: just in case someone wrote the magic character
  612. * five months ago... */
  613. expect_release = 0;
  614. /* scan to see whether or not we got the magic char. */
  615. for (i = 0; i != len; i++) {
  616. char c;
  617. if (get_user(c, data+i))
  618. return -EFAULT;
  619. if (c == 'V')
  620. expect_release = 42;
  621. }
  622. }
  623. /* someone wrote to us, we should reload the timer */
  624. hpwdt_ping();
  625. }
  626. return len;
  627. }
  628. static struct watchdog_info ident = {
  629. .options = WDIOF_SETTIMEOUT |
  630. WDIOF_KEEPALIVEPING |
  631. WDIOF_MAGICCLOSE,
  632. .identity = "HP iLO2 HW Watchdog Timer",
  633. };
  634. static long hpwdt_ioctl(struct file *file, unsigned int cmd,
  635. unsigned long arg)
  636. {
  637. void __user *argp = (void __user *)arg;
  638. int __user *p = argp;
  639. int new_margin;
  640. int ret = -ENOTTY;
  641. switch (cmd) {
  642. case WDIOC_GETSUPPORT:
  643. ret = 0;
  644. if (copy_to_user(argp, &ident, sizeof(ident)))
  645. ret = -EFAULT;
  646. break;
  647. case WDIOC_GETSTATUS:
  648. case WDIOC_GETBOOTSTATUS:
  649. ret = put_user(0, p);
  650. break;
  651. case WDIOC_KEEPALIVE:
  652. hpwdt_ping();
  653. ret = 0;
  654. break;
  655. case WDIOC_SETTIMEOUT:
  656. ret = get_user(new_margin, p);
  657. if (ret)
  658. break;
  659. ret = hpwdt_change_timer(new_margin);
  660. if (ret)
  661. break;
  662. hpwdt_ping();
  663. /* Fall */
  664. case WDIOC_GETTIMEOUT:
  665. ret = put_user(soft_margin, p);
  666. break;
  667. }
  668. return ret;
  669. }
  670. /*
  671. * Kernel interfaces
  672. */
  673. static struct file_operations hpwdt_fops = {
  674. .owner = THIS_MODULE,
  675. .llseek = no_llseek,
  676. .write = hpwdt_write,
  677. .unlocked_ioctl = hpwdt_ioctl,
  678. .open = hpwdt_open,
  679. .release = hpwdt_release,
  680. };
  681. static struct miscdevice hpwdt_miscdev = {
  682. .minor = WATCHDOG_MINOR,
  683. .name = "watchdog",
  684. .fops = &hpwdt_fops,
  685. };
  686. static struct notifier_block die_notifier = {
  687. .notifier_call = hpwdt_pretimeout,
  688. .priority = 0x7FFFFFFF,
  689. };
  690. /*
  691. * Init & Exit
  692. */
  693. static int __devinit hpwdt_init_one(struct pci_dev *dev,
  694. const struct pci_device_id *ent)
  695. {
  696. int retval;
  697. /*
  698. * First let's find out if we are on an iLO2 server. We will
  699. * not run on a legacy ASM box.
  700. */
  701. if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
  702. dev_warn(&dev->dev,
  703. "This server does not have an iLO2 ASIC.\n");
  704. return -ENODEV;
  705. }
  706. if (pci_enable_device(dev)) {
  707. dev_warn(&dev->dev,
  708. "Not possible to enable PCI Device: 0x%x:0x%x.\n",
  709. ent->vendor, ent->device);
  710. return -ENODEV;
  711. }
  712. pci_mem_addr = pci_iomap(dev, 1, 0x80);
  713. if (!pci_mem_addr) {
  714. dev_warn(&dev->dev,
  715. "Unable to detect the iLO2 server memory.\n");
  716. retval = -ENOMEM;
  717. goto error_pci_iomap;
  718. }
  719. hpwdt_timer_reg = pci_mem_addr + 0x70;
  720. hpwdt_timer_con = pci_mem_addr + 0x72;
  721. /* Make sure that we have a valid soft_margin */
  722. if (hpwdt_change_timer(soft_margin))
  723. hpwdt_change_timer(DEFAULT_MARGIN);
  724. /*
  725. * We need to map the ROM to get the CRU service.
  726. * For 32 bit Operating Systems we need to go through the 32 Bit
  727. * BIOS Service Directory
  728. * For 64 bit Operating Systems we get that service through SMBIOS.
  729. */
  730. retval = detect_cru_service();
  731. if (retval < 0) {
  732. dev_warn(&dev->dev,
  733. "Unable to detect the %d Bit CRU Service.\n",
  734. HPWDT_ARCH);
  735. goto error_get_cru;
  736. }
  737. /*
  738. * We know this is the only CRU call we need to make so lets keep as
  739. * few instructions as possible once the NMI comes in.
  740. */
  741. cmn_regs.u1.rah = 0x0D;
  742. cmn_regs.u1.ral = 0x02;
  743. retval = register_die_notifier(&die_notifier);
  744. if (retval != 0) {
  745. dev_warn(&dev->dev,
  746. "Unable to register a die notifier (err=%d).\n",
  747. retval);
  748. goto error_die_notifier;
  749. }
  750. retval = misc_register(&hpwdt_miscdev);
  751. if (retval < 0) {
  752. dev_warn(&dev->dev,
  753. "Unable to register miscdev on minor=%d (err=%d).\n",
  754. WATCHDOG_MINOR, retval);
  755. goto error_misc_register;
  756. }
  757. printk(KERN_INFO
  758. "hp Watchdog Timer Driver: 1.00"
  759. ", timer margin: %d seconds( nowayout=%d).\n",
  760. soft_margin, nowayout);
  761. return 0;
  762. error_misc_register:
  763. unregister_die_notifier(&die_notifier);
  764. error_die_notifier:
  765. if (cru_rom_addr)
  766. iounmap(cru_rom_addr);
  767. error_get_cru:
  768. pci_iounmap(dev, pci_mem_addr);
  769. error_pci_iomap:
  770. pci_disable_device(dev);
  771. return retval;
  772. }
  773. static void __devexit hpwdt_exit(struct pci_dev *dev)
  774. {
  775. if (!nowayout)
  776. hpwdt_stop();
  777. misc_deregister(&hpwdt_miscdev);
  778. unregister_die_notifier(&die_notifier);
  779. if (cru_rom_addr)
  780. iounmap(cru_rom_addr);
  781. pci_iounmap(dev, pci_mem_addr);
  782. pci_disable_device(dev);
  783. }
  784. static struct pci_driver hpwdt_driver = {
  785. .name = "hpwdt",
  786. .id_table = hpwdt_devices,
  787. .probe = hpwdt_init_one,
  788. .remove = __devexit_p(hpwdt_exit),
  789. };
  790. static void __exit hpwdt_cleanup(void)
  791. {
  792. pci_unregister_driver(&hpwdt_driver);
  793. }
  794. static int __init hpwdt_init(void)
  795. {
  796. return pci_register_driver(&hpwdt_driver);
  797. }
  798. MODULE_AUTHOR("Tom Mingarelli");
  799. MODULE_DESCRIPTION("hp watchdog driver");
  800. MODULE_LICENSE("GPL");
  801. MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
  802. module_param(soft_margin, int, 0);
  803. MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
  804. module_param(nowayout, int, 0);
  805. MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
  806. __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  807. module_init(hpwdt_init);
  808. module_exit(hpwdt_cleanup);