hpt34x.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/drivers/ide/hpt34x.c Version 0.31 June. 9, 2000
  3.  *
  4.  * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
  5.  * May be copied or modified under the terms of the GNU General Public License
  6.  *
  7.  *
  8.  * 00:12.0 Unknown mass storage controller:
  9.  * Triones Technologies, Inc.
  10.  * Unknown device 0003 (rev 01)
  11.  *
  12.  * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010)
  13.  * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030)
  14.  * hde: DMA 2  (0x0000 0x0002) (0x0000 0x0010)
  15.  * hdf: DMA 2  (0x0002 0x0012) (0x0010 0x0030)
  16.  * hdg: DMA 1  (0x0012 0x0052) (0x0030 0x0070)
  17.  * hdh: DMA 1  (0x0052 0x0252) (0x0070 0x00f0)
  18.  *
  19.  * ide-pci.c reference
  20.  *
  21.  * Since there are two cards that report almost identically,
  22.  * the only discernable difference is the values reported in pcicmd.
  23.  * Booting-BIOS card or HPT363 :: pcicmd == 0x07
  24.  * Non-bootable card or HPT343 :: pcicmd == 0x05
  25.  */
  26. #include <linux/config.h>
  27. #include <linux/types.h>
  28. #include <linux/kernel.h>
  29. #include <linux/delay.h>
  30. #include <linux/timer.h>
  31. #include <linux/mm.h>
  32. #include <linux/ioport.h>
  33. #include <linux/blkdev.h>
  34. #include <linux/hdreg.h>
  35. #include <linux/interrupt.h>
  36. #include <linux/pci.h>
  37. #include <linux/init.h>
  38. #include <linux/ide.h>
  39. #include <asm/io.h>
  40. #include <asm/irq.h>
  41. #include "ide_modes.h"
  42. #ifndef SPLIT_BYTE
  43. #define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
  44. #endif
  45. #define HPT343_DEBUG_DRIVE_INFO 0
  46. #undef DISPLAY_HPT34X_TIMINGS
  47. #if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS)
  48. #include <linux/stat.h>
  49. #include <linux/proc_fs.h>
  50. static int hpt34x_get_info(char *, char **, off_t, int);
  51. extern int (*hpt34x_display_info)(char *, char **, off_t, int); /* ide-proc.c */
  52. extern char *ide_media_verbose(ide_drive_t *);
  53. static struct pci_dev *bmide_dev;
  54. static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count)
  55. {
  56. char *p = buffer;
  57. u32 bibma = pci_resource_start(bmide_dev, 4);
  58. u8  c0 = 0, c1 = 0;
  59.         /*
  60.          * at that point bibma+0x2 et bibma+0xa are byte registers
  61.          * to investigate:
  62.          */
  63. c0 = inb_p((unsigned short)bibma + 0x02);
  64. c1 = inb_p((unsigned short)bibma + 0x0a);
  65. p += sprintf(p, "n                                HPT34X Chipset.n");
  66. p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------n");
  67. p += sprintf(p, "                %sabled                         %sabledn",
  68. (c0&0x80) ? "dis" : " en",
  69. (c1&0x80) ? "dis" : " en");
  70. p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------n");
  71. p += sprintf(p, "DMA enabled:    %s              %s             %s               %sn",
  72. (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
  73. (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
  74. p += sprintf(p, "UDMAn");
  75. p += sprintf(p, "DMAn");
  76. p += sprintf(p, "PIOn");
  77. return p-buffer; /* => must be less than 4k! */
  78. }
  79. #endif  /* defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) */
  80. byte hpt34x_proc = 0;
  81. extern char *ide_xfer_verbose (byte xfer_rate);
  82. static void hpt34x_clear_chipset (ide_drive_t *drive)
  83. {
  84. unsigned int reg1 = 0, tmp1 = 0;
  85. unsigned int reg2 = 0, tmp2 = 0;
  86. pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, &reg1);
  87. pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, &reg2);
  88. tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
  89. tmp2 = (reg2 & ~(0x11 << drive->dn));
  90. pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1);
  91. pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2);
  92. }
  93. static int hpt34x_tune_chipset (ide_drive_t *drive, byte speed)
  94. {
  95. int err;
  96. byte hi_speed, lo_speed;
  97. unsigned int reg1 = 0, tmp1 = 0;
  98. unsigned int reg2 = 0, tmp2 = 0;
  99. SPLIT_BYTE(speed, hi_speed, lo_speed);
  100. if (hi_speed & 7) {
  101. hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
  102. } else {
  103. lo_speed <<= 5;
  104. lo_speed >>= 5;
  105. }
  106. pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, &reg1);
  107. pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, &reg2);
  108. tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
  109. tmp2 = ((hi_speed << drive->dn) | reg2);
  110. err = ide_config_drive_speed(drive, speed);
  111. pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1);
  112. pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2);
  113. if (!drive->init_speed)
  114. drive->init_speed = speed;
  115. #if HPT343_DEBUG_DRIVE_INFO
  116. printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" 
  117. " (0x%02x 0x%02x) 0x%04xn",
  118. drive->name, ide_xfer_verbose(speed),
  119. drive->dn, reg1, tmp1, reg2, tmp2,
  120. hi_speed, lo_speed, err);
  121. #endif /* HPT343_DEBUG_DRIVE_INFO */
  122. drive->current_speed = speed;
  123. return(err);
  124. }
  125. static void config_chipset_for_pio (ide_drive_t *drive)
  126. {
  127. unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
  128. unsigned short xfer_pio = drive->id->eide_pio_modes;
  129. byte timing, speed, pio;
  130. pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
  131. if (xfer_pio> 4)
  132. xfer_pio = 0;
  133. if (drive->id->eide_pio_iordy > 0) {
  134. for (xfer_pio = 5;
  135. xfer_pio>0 &&
  136. drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
  137. xfer_pio--);
  138. } else {
  139. xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
  140.    (drive->id->eide_pio_modes & 2) ? 0x04 :
  141.    (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
  142. }
  143. timing = (xfer_pio >= pio) ? xfer_pio : pio;
  144. switch(timing) {
  145. case 4: speed = XFER_PIO_4;break;
  146. case 3: speed = XFER_PIO_3;break;
  147. case 2: speed = XFER_PIO_2;break;
  148. case 1: speed = XFER_PIO_1;break;
  149. default:
  150. speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
  151. break;
  152. }
  153. (void) hpt34x_tune_chipset(drive, speed);
  154. }
  155. static void hpt34x_tune_drive (ide_drive_t *drive, byte pio)
  156. {
  157. byte speed;
  158. switch(pio) {
  159. case 4: speed = XFER_PIO_4;break;
  160. case 3: speed = XFER_PIO_3;break;
  161. case 2: speed = XFER_PIO_2;break;
  162. case 1: speed = XFER_PIO_1;break;
  163. default: speed = XFER_PIO_0;break;
  164. }
  165. hpt34x_clear_chipset(drive);
  166. (void) hpt34x_tune_chipset(drive, speed);
  167. }
  168. #ifdef CONFIG_BLK_DEV_IDEDMA
  169. /*
  170.  * This allows the configuration of ide_pci chipset registers
  171.  * for cards that learn about the drive's UDMA, DMA, PIO capabilities
  172.  * after the drive is reported by the OS.  Initally for designed for
  173.  * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
  174.  */
  175. static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
  176. {
  177. struct hd_driveid *id = drive->id;
  178. byte speed = 0x00;
  179. if (drive->media != ide_disk)
  180. return ((int) ide_dma_off_quietly);
  181. hpt34x_clear_chipset(drive);
  182. if ((id->dma_ultra & 0x0010) && ultra) {
  183. speed = XFER_UDMA_2;
  184. } else if ((id->dma_ultra & 0x0008) && ultra) {
  185. speed = XFER_UDMA_2;
  186. } else if ((id->dma_ultra & 0x0004) && ultra) {
  187. speed = XFER_UDMA_2;
  188. } else if ((id->dma_ultra & 0x0002) && ultra) {
  189. speed = XFER_UDMA_1;
  190. } else if ((id->dma_ultra & 0x0001) && ultra) {
  191. speed = XFER_UDMA_0;
  192. } else if (id->dma_mword & 0x0004) {
  193. speed = XFER_MW_DMA_2;
  194. } else if (id->dma_mword & 0x0002) {
  195. speed = XFER_MW_DMA_1;
  196. } else if (id->dma_mword & 0x0001) {
  197. speed = XFER_MW_DMA_0;
  198. } else if (id->dma_1word & 0x0004) {
  199. speed = XFER_SW_DMA_2;
  200. } else if (id->dma_1word & 0x0002) {
  201. speed = XFER_SW_DMA_1;
  202. } else if (id->dma_1word & 0x0001) {
  203. speed = XFER_SW_DMA_0;
  204.         } else {
  205. return ((int) ide_dma_off_quietly);
  206. }
  207. (void) hpt34x_tune_chipset(drive, speed);
  208. return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off :
  209. ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
  210. ((id->dma_mword >> 8) & 7) ? ide_dma_on :
  211. ((id->dma_1word >> 8) & 7) ? ide_dma_on :
  212.      ide_dma_off_quietly);
  213. }
  214. static int config_drive_xfer_rate (ide_drive_t *drive)
  215. {
  216. struct hd_driveid *id = drive->id;
  217. ide_dma_action_t dma_func = ide_dma_on;
  218. if (id && (id->capability & 1) && HWIF(drive)->autodma) {
  219. /* Consult the list of known "bad" drives */
  220. if (ide_dmaproc(ide_dma_bad_drive, drive)) {
  221. dma_func = ide_dma_off;
  222. goto fast_ata_pio;
  223. }
  224. dma_func = ide_dma_off_quietly;
  225. if (id->field_valid & 4) {
  226. if (id->dma_ultra & 0x0007) {
  227. /* Force if Capable UltraDMA */
  228. dma_func = config_chipset_for_dma(drive, 1);
  229. if ((id->field_valid & 2) &&
  230.     (dma_func != ide_dma_on))
  231. goto try_dma_modes;
  232. }
  233. } else if (id->field_valid & 2) {
  234. try_dma_modes:
  235. if ((id->dma_mword & 0x0007) ||
  236.     (id->dma_1word & 0x0007)) {
  237. /* Force if Capable regular DMA modes */
  238. dma_func = config_chipset_for_dma(drive, 0);
  239. if (dma_func != ide_dma_on)
  240. goto no_dma_set;
  241. }
  242. } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
  243. if (id->eide_dma_time > 150) {
  244. goto no_dma_set;
  245. }
  246. /* Consult the list of known "good" drives */
  247. dma_func = config_chipset_for_dma(drive, 0);
  248. if (dma_func != ide_dma_on)
  249. goto no_dma_set;
  250. } else {
  251. goto fast_ata_pio;
  252. }
  253. } else if ((id->capability & 8) || (id->field_valid & 2)) {
  254. fast_ata_pio:
  255. dma_func = ide_dma_off_quietly;
  256. no_dma_set:
  257. config_chipset_for_pio(drive);
  258. }
  259. #ifndef CONFIG_HPT34X_AUTODMA
  260. if (dma_func == ide_dma_on)
  261. dma_func = ide_dma_off;
  262. #endif /* CONFIG_HPT34X_AUTODMA */
  263. return HWIF(drive)->dmaproc(dma_func, drive);
  264. }
  265. /*
  266.  * hpt34x_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
  267.  *
  268.  * This is specific to the HPT343 UDMA bios-less chipset
  269.  * and HPT345 UDMA bios chipset (stamped HPT363)
  270.  * by HighPoint|Triones Technologies, Inc.
  271.  */
  272. int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
  273. {
  274. ide_hwif_t *hwif = HWIF(drive);
  275. unsigned long dma_base = hwif->dma_base;
  276. unsigned int count, reading = 0;
  277. byte dma_stat;
  278. switch (func) {
  279. case ide_dma_check:
  280. return config_drive_xfer_rate(drive);
  281. case ide_dma_read:
  282. reading = 1 << 3;
  283. case ide_dma_write:
  284. if (!(count = ide_build_dmatable(drive, func)))
  285. return 1; /* try PIO instead of DMA */
  286. outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
  287. reading |= 0x01;
  288. outb(reading, dma_base); /* specify r/w */
  289. outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
  290. drive->waiting_for_dma = 1;
  291. if (drive->media != ide_disk)
  292. return 0;
  293. ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
  294. OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
  295. return 0;
  296. case ide_dma_end: /* returns 1 on error, 0 otherwise */
  297. drive->waiting_for_dma = 0;
  298. outb(inb(dma_base)&~1, dma_base); /* stop DMA */
  299. dma_stat = inb(dma_base+2); /* get DMA status */
  300. outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
  301. ide_destroy_dmatable(drive); /* purge DMA mappings */
  302. return (dma_stat & 7) != 4; /* verify good DMA status */
  303. default:
  304. break;
  305. }
  306. return ide_dmaproc(func, drive); /* use standard DMA stuff */
  307. }
  308. #endif /* CONFIG_BLK_DEV_IDEDMA */
  309. /*
  310.  * If the BIOS does not set the IO base addaress to XX00, 343 will fail.
  311.  */
  312. #define HPT34X_PCI_INIT_REG 0x80
  313. unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name)
  314. {
  315. int i = 0;
  316. unsigned long hpt34xIoBase = pci_resource_start(dev, 4);
  317. unsigned short cmd;
  318. unsigned long flags;
  319. __save_flags(flags); /* local CPU only */
  320. __cli(); /* local CPU only */
  321. pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00);
  322. pci_read_config_word(dev, PCI_COMMAND, &cmd);
  323. if (cmd & PCI_COMMAND_MEMORY) {
  324. if (pci_resource_start(dev, PCI_ROM_RESOURCE)) {
  325. pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
  326. printk(KERN_INFO "HPT345: ROM enabled at 0x%08lxn", dev->resource[PCI_ROM_RESOURCE].start);
  327. }
  328. pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
  329. } else {
  330. pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
  331. }
  332. pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO);
  333. dev->resource[0].start = (hpt34xIoBase + 0x20);
  334. dev->resource[1].start = (hpt34xIoBase + 0x34);
  335. dev->resource[2].start = (hpt34xIoBase + 0x28);
  336. dev->resource[3].start = (hpt34xIoBase + 0x3c);
  337. for(i=0; i<4; i++)
  338. dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
  339. /*
  340.  * Since 20-23 can be assigned and are R/W, we correct them.
  341.  */
  342. pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, dev->resource[0].start);
  343. pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start);
  344. pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start);
  345. pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start);
  346. pci_write_config_word(dev, PCI_COMMAND, cmd);
  347. __restore_flags(flags); /* local CPU only */
  348. #if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS)
  349. if (!hpt34x_proc) {
  350. hpt34x_proc = 1;
  351. bmide_dev = dev;
  352. hpt34x_display_info = &hpt34x_get_info;
  353. }
  354. #endif /* DISPLAY_HPT34X_TIMINGS && CONFIG_PROC_FS */
  355. return dev->irq;
  356. }
  357. void __init ide_init_hpt34x (ide_hwif_t *hwif)
  358. {
  359. hwif->tuneproc = &hpt34x_tune_drive;
  360. hwif->speedproc = &hpt34x_tune_chipset;
  361. #ifdef CONFIG_BLK_DEV_IDEDMA
  362. if (hwif->dma_base) {
  363. unsigned short pcicmd = 0;
  364. pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
  365. if (!noautodma)
  366. hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
  367. else
  368. hwif->autodma = 0;
  369. hwif->dmaproc = &hpt34x_dmaproc;
  370. } else {
  371. hwif->drives[0].autotune = 1;
  372. hwif->drives[1].autotune = 1;
  373. }
  374. #else /* !CONFIG_BLK_DEV_IDEDMA */
  375. hwif->drives[0].autotune = 1;
  376. hwif->drives[1].autotune = 1;
  377. hwif->autodma = 0;
  378. #endif /* CONFIG_BLK_DEV_IDEDMA */
  379. }