Changeset 30

Show
Ignore:
Timestamp:
12/04/98 04:49:32 (14 years ago)
Author:
phil
Message:

(Phil) OK, here is the first shot at integrating PIIX4 support in the new
lm_sensors2 project. It was *very* easy to copy-and-paste it in, so I'm
hoping that it won't include any new bugs. It builds and compiles, but
I wasn't able to test it (under 2.1.131) until we get some compatibility
problems solved. There is probably a little cleaning up to do yet, but
everything looks like it is happy. Test it under 2.0.x and let me know
what happens.

Location:
lm-sensors/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/kernel/busses/i2c-piix4.c

    r22 r30  
    11/* 
    22    smbus.c - A Linux module for reading sensor data. 
    3     Copyright (c) 1998  Frodo Looijaard <frodol@dds.nl>  
     3    Copyright (c) 1998  Frodo Looijaard <frodol@dds.nl> and 
     4    Philip Edelbrock <phil@netroedge.com> 
    45 
    56    This program is free software; you can redistribute it and/or modify 
     
    2021/* Note: New PCI (non-BIOS) interface introduced in 2.1.54! */ 
    2122 
     23#include <linux/pci.h> 
     24#include <asm/io.h> 
    2225#include <linux/module.h> 
    2326#include <linux/kernel.h> 
     
    2528#include "smbus.h" 
    2629#include "version.h" 
     30#include "compat.h" 
     31#include "piix4.h" 
    2732 
    2833static int piix4_init(void); 
     
    3136static s32 piix4_access(u8 addr, char read_write, 
    3237                        u8 command, int size, union smbus_data * data); 
     38/* Internal functions */ 
     39static void do_pause( unsigned int amount ); 
     40static int SMBus_PIIX4_Transaction(void); 
    3341 
    3442#ifdef MODULE 
     
    4048static int piix4_initialized; 
    4149 
     50/* Global variables  -- At least some of these may be modified/moved later */ 
     51static unsigned short PIIX4_smba = 0; 
     52static struct semaphore smbus_piix4_sem = MUTEX; 
     53 
     54 
    4255/* Detect whether a PIIX4 can be found, and initialize it, where necessary.  
    4356   Return -ENODEV if not found. */ 
    4457int piix4_setup(void) 
    4558{ 
    46   return -ENODEV; 
    47   /* TO BE WRITTEN! */ 
     59  int error_return=0; 
     60  unsigned char temp; 
     61 
     62#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     63  struct pci_dev *PIIX4_dev; 
     64#else 
     65  unsigned char PIIX4_bus, PIIX4_devfn; 
     66#endif 
     67 
     68  if (pci_present() == 0) { 
     69    printk("SMBus: Error: No PCI-bus found!\n"); 
     70    error_return=-ENODEV; 
     71  } else { 
     72 
     73#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     74    PIIX4_dev = pci_find_device(PCI_VENDOR_ID_INTEL,  
     75                                 PCI_DEVICE_ID_INTEL_82371AB_0, NULL); 
     76    if(PIIX4_dev == NULL) { 
     77#else 
     78    if(pcibios_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,  
     79                           0, &PIIX4_bus, &PIIX4_devfn)) { 
     80#endif 
     81      printk("SMBus: Error: Can't detect PIIX4!\n"); 
     82      error_return=-ENODEV; 
     83    } else { 
     84#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     85      /* For some reason, pci_read_config fails here sometimes! */ 
     86      pcibios_read_config_word(PIIX4_dev->bus->number, PIIX4_dev->devfn | 3,  
     87                               SMBBA, &PIIX4_smba); 
     88#else 
     89      pci_read_config_word_united(PIIX4_dev, PIIX4_bus ,PIIX4_devfn | 3, 
     90                                  SMBBA,&PIIX4_smba); 
     91#endif 
     92      PIIX4_smba &= 0xfff0; 
     93      if (check_region(PIIX4_smba, 8)) { 
     94        printk("PIIX4_smb region 0x%x already in use!\n", 
     95               PIIX4_smba); 
     96        error_return=-ENODEV; 
     97      } else { 
     98#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     99        pcibios_read_config_byte(PIIX4_dev->bus->number,  
     100                PIIX4_dev->devfn | 3, SMBHSTCFG, &temp); 
     101#else 
     102        pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn | 3,  
     103                                    SMBHSTCFG, &temp); 
     104#endif 
     105#ifdef FORCE_PIIX4_ENABLE 
     106/* This should never need to be done, but has been noted that 
     107   many Dell machines have the SMBus interface on the PIIX4 
     108   disabled!? NOTE: This assumes I/O space and other allocations WERE 
     109   done by the Bios!  Don't complain if your hardware does weird  
     110   things after enabling this. :') Check for Bios updates before 
     111   resorting to this.  */ 
     112        if ((temp & 1) == 0) { 
     113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     114          pcibios_write_config_byte(PIIX4_dev->bus->number, PIIX4_dev->devfn | 3,  
     115                               SMBHSTCFG, temp | 1); 
     116#else 
     117          pcibios_write_config_byte(PIIX4_bus, PIIX4_devfn | 3, SMBHSTCFG, temp | 1); 
     118#endif 
     119          printk("SMBus: WARNING: PIIX4 SMBus interface has been FORCEFULLY ENABLED!!\n"); 
     120          /* Update configuration value */ 
     121          pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn | 3, SMBHSTCFG, &temp); 
     122          /* Note: We test the bit again in the next 'if' just to be sure... */ 
     123        } 
     124#endif 
     125        if ((temp & 1) == 0) { 
     126          printk("SMBUS: Error: Host SMBus controller not enabled!\n");      
     127          piix4_initialized=0; 
     128          error_return=-ENODEV; 
     129        } else { 
     130                /* Everything is happy, let's grab the memory and set things up. */ 
     131                request_region(PIIX4_smba, 8, "SMBus");        
     132                piix4_initialized=1; 
     133        } 
     134#ifdef DEBUG 
     135        if ((temp & 0x0E) == 8) 
     136          printk("SMBUS: PIIX4 using Interrupt 9 for SMBus.\n"); 
     137        else if ((temp & 0x0E) == 0) 
     138          printk("SMBUS: PIIX4 using Interrupt SMI# for SMBus.\n"); 
     139        else  
     140          printk( "SMBUS: PIIX4: Illegal Interrupt configuration (or code out of date)!\n"); 
     141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     142        pcibios_read_config_byte(PIIX4_dev->bus->number,  
     143                PIIX4_dev->devfn | 3, SMBREV, &temp); 
     144#else 
     145        pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn | 3,  
     146                                    SMBREV, &temp); 
     147#endif 
     148        printk("SMBUS: SMBREV = 0x%X\n",temp); 
     149#endif 
     150      } 
     151    } 
     152  if (error_return) 
     153    printk("SMBus setup failed.\n"); 
     154#ifdef DEBUG 
     155  else 
     156    printk("PIIX4_smba = 0x%X\n",PIIX4_smba); 
     157#endif 
     158  } 
     159  return error_return; 
     160} 
     161 
     162/* Internally used pause function */ 
     163void do_pause( unsigned int amount ) 
     164{ 
     165      current->state = TASK_INTERRUPTIBLE; 
     166      schedule_timeout(amount); 
     167} 
     168 
     169/* Another internally used function */ 
     170int SMBus_PIIX4_Transaction(void)  
     171{ 
     172  int temp; 
     173  int result=0; 
     174  int timeout=0; 
     175 
     176  /* Make sure the SMBus host is ready to start transmitting */ 
     177  if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     178#ifdef DEBUG 
     179    printk("SMBus: SMBus_Read: SMBus busy (%02x). Resetting... ",temp); 
     180#endif 
     181    outb_p(temp, SMBHSTSTS); 
     182    if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     183#ifdef DEBUG 
     184      printk("Failed! (%02x)\n",temp); 
     185#endif 
     186      return -1; 
     187    } else { 
     188#ifdef DEBUG 
     189      printk("Successfull!\n"); 
     190#endif 
     191    } 
     192  } 
     193 
     194  /* start the transaction by setting bit 6 */ 
     195  outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);  
     196 
     197  /* Wait for a fraction of a second! (See PIIX4 docs errata) */ 
     198  do_pause(1); 
     199 
     200  /* Poll Host_busy bit */ 
     201  temp=inb_p(SMBHSTSTS) & 0x01; 
     202  while (temp & (timeout++ < MAX_TIMEOUT)) { 
     203    /* Wait for a while and try again*/ 
     204    do_pause(1); 
     205    temp = inb_p(SMBHSTSTS) & 0x01; 
     206  } 
     207 
     208  /* If the SMBus is still busy, we give up */ 
     209  if (timeout >= MAX_TIMEOUT) { 
     210#ifdef DEBUG 
     211    printk("SMBus: SMBus_Read: SMBus Timeout!\n");  
     212    result = -1; 
     213#endif 
     214  } 
     215 
     216  temp = inb_p(SMBHSTSTS); 
     217 
     218  if (temp  & 0x10) { 
     219    result = -1; 
     220#ifdef DEBUG 
     221    printk("SMBus error: Failed bus transaction\n"); 
     222#endif 
     223  } 
     224 
     225  if (temp & 0x08) { 
     226    result = -1; 
     227    printk("SMBus error: Bus collision! SMBus may be locked until next hard reset. (sorry!)\n"); 
     228    /* Clock stops and slave is stuck in mid-transmission */ 
     229  } 
     230 
     231  if (temp & 0x04) { 
     232    result = -1; 
     233#ifdef DEBUG 
     234    printk("SMBus error: no response!\n"); 
     235#endif 
     236  } 
     237 
     238  if (inb_p(SMBHSTSTS) != 0x00) 
     239    outb_p( inb(SMBHSTSTS), SMBHSTSTS); 
     240 
     241  if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     242#ifdef DEBUG 
     243    printk("SMBus error: Failed reset at end of transaction (%02x)\n",temp); 
     244#endif 
     245  } 
     246  return result; 
    48247} 
    49248 
     
    52251                 u8 command, int size, union smbus_data * data) 
    53252{ 
    54   /* TO BE WRITTEN! */ 
    55   return -1; 
    56 } 
     253  int i,len; 
     254 
     255  down(&smbus_piix4_sem); 
     256 
     257  outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
     258 
     259  switch(size) { 
     260    case SMBUS_QUICK: 
     261      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     262      break; 
     263    case SMBUS_BYTE: 
     264      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     265      if (read_write == SMBUS_WRITE) 
     266        outb_p(command, SMBHSTCMD); 
     267      break; 
     268    case SMBUS_BYTE_DATA: 
     269      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     270      outb_p(command, SMBHSTCMD); 
     271      if (read_write == SMBUS_WRITE) 
     272        outb_p(data->byte,SMBHSTDAT0); 
     273      break; 
     274    case SMBUS_WORD_DATA: 
     275      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     276      outb_p(command, SMBHSTCMD); 
     277      if (read_write == SMBUS_WRITE) { 
     278        outb_p(data->word & 0xff,SMBHSTDAT0); 
     279        outb_p((data->word & 0xff00) >> 8,SMBHSTDAT1); 
     280      } 
     281      break; 
     282    case SMBUS_BLOCK_DATA: 
     283      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     284      outb_p(command, SMBHSTCMD); 
     285      if (read_write == SMBUS_WRITE) { 
     286        len = data->block[0]; 
     287        if (len < 0)  
     288          len = 0; 
     289        if (len > 32) 
     290          len = 32; 
     291        outb_p(len,SMBHSTDAT0); 
     292        i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 
     293        for (i = 1; i <= len; i ++) 
     294          outb_p(data->block[i],SMBBLKDAT); 
     295        break; 
     296      } 
     297  } 
     298 
     299  if (SMBus_PIIX4_Transaction()) { /* Error in transaction */  
     300    up(&smbus_piix4_sem); 
     301    return -1;  
     302  } 
     303 
     304  if ((read_write == SMBUS_WRITE) || (size == SMBUS_QUICK)) { 
     305    up(&smbus_piix4_sem); 
     306    return 0; 
     307  } 
     308 
    57309 
    58310 
     
    62314  printk("piix4.o version %s (%s)\n",LM_VERSION,LM_DATE); 
    63315#ifdef DEBUG 
     316/* PE- It might be good to make this a permanent part of the code! */ 
    64317  if (piix4_initialized) { 
    65318    printk("piix4.o: Oops, piix4_init called a second time!\n"); 
     
    97350      return res; 
    98351    } else 
    99       piix4_initialized--; 
     352      piix4_initialized=0; 
    100353  } 
    101354  if (piix4_initialized >= 1) { 
    102     /* Undo anything piix4_setup did */ 
    103     piix4_initialized--; 
     355    if (piix4_initialized) { 
     356                release_region(PIIX4_smba, 8); 
     357                piix4_initialized=0; 
     358    } 
    104359  } 
    105360  return 0; 
     
    108363#ifdef MODULE 
    109364 
    110 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 
     365MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>"); 
    111366MODULE_DESCRIPTION("PIIX4 SMBus driver"); 
    112367 
  • lm-sensors/trunk/src/piix4.c

    r22 r30  
    11/* 
    22    smbus.c - A Linux module for reading sensor data. 
    3     Copyright (c) 1998  Frodo Looijaard <frodol@dds.nl>  
     3    Copyright (c) 1998  Frodo Looijaard <frodol@dds.nl> and 
     4    Philip Edelbrock <phil@netroedge.com> 
    45 
    56    This program is free software; you can redistribute it and/or modify 
     
    2021/* Note: New PCI (non-BIOS) interface introduced in 2.1.54! */ 
    2122 
     23#include <linux/pci.h> 
     24#include <asm/io.h> 
    2225#include <linux/module.h> 
    2326#include <linux/kernel.h> 
     
    2528#include "smbus.h" 
    2629#include "version.h" 
     30#include "compat.h" 
     31#include "piix4.h" 
    2732 
    2833static int piix4_init(void); 
     
    3136static s32 piix4_access(u8 addr, char read_write, 
    3237                        u8 command, int size, union smbus_data * data); 
     38/* Internal functions */ 
     39static void do_pause( unsigned int amount ); 
     40static int SMBus_PIIX4_Transaction(void); 
    3341 
    3442#ifdef MODULE 
     
    4048static int piix4_initialized; 
    4149 
     50/* Global variables  -- At least some of these may be modified/moved later */ 
     51static unsigned short PIIX4_smba = 0; 
     52static struct semaphore smbus_piix4_sem = MUTEX; 
     53 
     54 
    4255/* Detect whether a PIIX4 can be found, and initialize it, where necessary.  
    4356   Return -ENODEV if not found. */ 
    4457int piix4_setup(void) 
    4558{ 
    46   return -ENODEV; 
    47   /* TO BE WRITTEN! */ 
     59  int error_return=0; 
     60  unsigned char temp; 
     61 
     62#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     63  struct pci_dev *PIIX4_dev; 
     64#else 
     65  unsigned char PIIX4_bus, PIIX4_devfn; 
     66#endif 
     67 
     68  if (pci_present() == 0) { 
     69    printk("SMBus: Error: No PCI-bus found!\n"); 
     70    error_return=-ENODEV; 
     71  } else { 
     72 
     73#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     74    PIIX4_dev = pci_find_device(PCI_VENDOR_ID_INTEL,  
     75                                 PCI_DEVICE_ID_INTEL_82371AB_0, NULL); 
     76    if(PIIX4_dev == NULL) { 
     77#else 
     78    if(pcibios_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,  
     79                           0, &PIIX4_bus, &PIIX4_devfn)) { 
     80#endif 
     81      printk("SMBus: Error: Can't detect PIIX4!\n"); 
     82      error_return=-ENODEV; 
     83    } else { 
     84#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     85      /* For some reason, pci_read_config fails here sometimes! */ 
     86      pcibios_read_config_word(PIIX4_dev->bus->number, PIIX4_dev->devfn | 3,  
     87                               SMBBA, &PIIX4_smba); 
     88#else 
     89      pci_read_config_word_united(PIIX4_dev, PIIX4_bus ,PIIX4_devfn | 3, 
     90                                  SMBBA,&PIIX4_smba); 
     91#endif 
     92      PIIX4_smba &= 0xfff0; 
     93      if (check_region(PIIX4_smba, 8)) { 
     94        printk("PIIX4_smb region 0x%x already in use!\n", 
     95               PIIX4_smba); 
     96        error_return=-ENODEV; 
     97      } else { 
     98#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     99        pcibios_read_config_byte(PIIX4_dev->bus->number,  
     100                PIIX4_dev->devfn | 3, SMBHSTCFG, &temp); 
     101#else 
     102        pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn | 3,  
     103                                    SMBHSTCFG, &temp); 
     104#endif 
     105#ifdef FORCE_PIIX4_ENABLE 
     106/* This should never need to be done, but has been noted that 
     107   many Dell machines have the SMBus interface on the PIIX4 
     108   disabled!? NOTE: This assumes I/O space and other allocations WERE 
     109   done by the Bios!  Don't complain if your hardware does weird  
     110   things after enabling this. :') Check for Bios updates before 
     111   resorting to this.  */ 
     112        if ((temp & 1) == 0) { 
     113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     114          pcibios_write_config_byte(PIIX4_dev->bus->number, PIIX4_dev->devfn | 3,  
     115                               SMBHSTCFG, temp | 1); 
     116#else 
     117          pcibios_write_config_byte(PIIX4_bus, PIIX4_devfn | 3, SMBHSTCFG, temp | 1); 
     118#endif 
     119          printk("SMBus: WARNING: PIIX4 SMBus interface has been FORCEFULLY ENABLED!!\n"); 
     120          /* Update configuration value */ 
     121          pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn | 3, SMBHSTCFG, &temp); 
     122          /* Note: We test the bit again in the next 'if' just to be sure... */ 
     123        } 
     124#endif 
     125        if ((temp & 1) == 0) { 
     126          printk("SMBUS: Error: Host SMBus controller not enabled!\n");      
     127          piix4_initialized=0; 
     128          error_return=-ENODEV; 
     129        } else { 
     130                /* Everything is happy, let's grab the memory and set things up. */ 
     131                request_region(PIIX4_smba, 8, "SMBus");        
     132                piix4_initialized=1; 
     133        } 
     134#ifdef DEBUG 
     135        if ((temp & 0x0E) == 8) 
     136          printk("SMBUS: PIIX4 using Interrupt 9 for SMBus.\n"); 
     137        else if ((temp & 0x0E) == 0) 
     138          printk("SMBUS: PIIX4 using Interrupt SMI# for SMBus.\n"); 
     139        else  
     140          printk( "SMBUS: PIIX4: Illegal Interrupt configuration (or code out of date)!\n"); 
     141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) 
     142        pcibios_read_config_byte(PIIX4_dev->bus->number,  
     143                PIIX4_dev->devfn | 3, SMBREV, &temp); 
     144#else 
     145        pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn | 3,  
     146                                    SMBREV, &temp); 
     147#endif 
     148        printk("SMBUS: SMBREV = 0x%X\n",temp); 
     149#endif 
     150      } 
     151    } 
     152  if (error_return) 
     153    printk("SMBus setup failed.\n"); 
     154#ifdef DEBUG 
     155  else 
     156    printk("PIIX4_smba = 0x%X\n",PIIX4_smba); 
     157#endif 
     158  } 
     159  return error_return; 
     160} 
     161 
     162/* Internally used pause function */ 
     163void do_pause( unsigned int amount ) 
     164{ 
     165      current->state = TASK_INTERRUPTIBLE; 
     166      schedule_timeout(amount); 
     167} 
     168 
     169/* Another internally used function */ 
     170int SMBus_PIIX4_Transaction(void)  
     171{ 
     172  int temp; 
     173  int result=0; 
     174  int timeout=0; 
     175 
     176  /* Make sure the SMBus host is ready to start transmitting */ 
     177  if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     178#ifdef DEBUG 
     179    printk("SMBus: SMBus_Read: SMBus busy (%02x). Resetting... ",temp); 
     180#endif 
     181    outb_p(temp, SMBHSTSTS); 
     182    if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     183#ifdef DEBUG 
     184      printk("Failed! (%02x)\n",temp); 
     185#endif 
     186      return -1; 
     187    } else { 
     188#ifdef DEBUG 
     189      printk("Successfull!\n"); 
     190#endif 
     191    } 
     192  } 
     193 
     194  /* start the transaction by setting bit 6 */ 
     195  outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);  
     196 
     197  /* Wait for a fraction of a second! (See PIIX4 docs errata) */ 
     198  do_pause(1); 
     199 
     200  /* Poll Host_busy bit */ 
     201  temp=inb_p(SMBHSTSTS) & 0x01; 
     202  while (temp & (timeout++ < MAX_TIMEOUT)) { 
     203    /* Wait for a while and try again*/ 
     204    do_pause(1); 
     205    temp = inb_p(SMBHSTSTS) & 0x01; 
     206  } 
     207 
     208  /* If the SMBus is still busy, we give up */ 
     209  if (timeout >= MAX_TIMEOUT) { 
     210#ifdef DEBUG 
     211    printk("SMBus: SMBus_Read: SMBus Timeout!\n");  
     212    result = -1; 
     213#endif 
     214  } 
     215 
     216  temp = inb_p(SMBHSTSTS); 
     217 
     218  if (temp  & 0x10) { 
     219    result = -1; 
     220#ifdef DEBUG 
     221    printk("SMBus error: Failed bus transaction\n"); 
     222#endif 
     223  } 
     224 
     225  if (temp & 0x08) { 
     226    result = -1; 
     227    printk("SMBus error: Bus collision! SMBus may be locked until next hard reset. (sorry!)\n"); 
     228    /* Clock stops and slave is stuck in mid-transmission */ 
     229  } 
     230 
     231  if (temp & 0x04) { 
     232    result = -1; 
     233#ifdef DEBUG 
     234    printk("SMBus error: no response!\n"); 
     235#endif 
     236  } 
     237 
     238  if (inb_p(SMBHSTSTS) != 0x00) 
     239    outb_p( inb(SMBHSTSTS), SMBHSTSTS); 
     240 
     241  if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     242#ifdef DEBUG 
     243    printk("SMBus error: Failed reset at end of transaction (%02x)\n",temp); 
     244#endif 
     245  } 
     246  return result; 
    48247} 
    49248 
     
    52251                 u8 command, int size, union smbus_data * data) 
    53252{ 
    54   /* TO BE WRITTEN! */ 
    55   return -1; 
    56 } 
     253  int i,len; 
     254 
     255  down(&smbus_piix4_sem); 
     256 
     257  outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
     258 
     259  switch(size) { 
     260    case SMBUS_QUICK: 
     261      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     262      break; 
     263    case SMBUS_BYTE: 
     264      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     265      if (read_write == SMBUS_WRITE) 
     266        outb_p(command, SMBHSTCMD); 
     267      break; 
     268    case SMBUS_BYTE_DATA: 
     269      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     270      outb_p(command, SMBHSTCMD); 
     271      if (read_write == SMBUS_WRITE) 
     272        outb_p(data->byte,SMBHSTDAT0); 
     273      break; 
     274    case SMBUS_WORD_DATA: 
     275      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     276      outb_p(command, SMBHSTCMD); 
     277      if (read_write == SMBUS_WRITE) { 
     278        outb_p(data->word & 0xff,SMBHSTDAT0); 
     279        outb_p((data->word & 0xff00) >> 8,SMBHSTDAT1); 
     280      } 
     281      break; 
     282    case SMBUS_BLOCK_DATA: 
     283      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
     284      outb_p(command, SMBHSTCMD); 
     285      if (read_write == SMBUS_WRITE) { 
     286        len = data->block[0]; 
     287        if (len < 0)  
     288          len = 0; 
     289        if (len > 32) 
     290          len = 32; 
     291        outb_p(len,SMBHSTDAT0); 
     292        i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 
     293        for (i = 1; i <= len; i ++) 
     294          outb_p(data->block[i],SMBBLKDAT); 
     295        break; 
     296      } 
     297  } 
     298 
     299  if (SMBus_PIIX4_Transaction()) { /* Error in transaction */  
     300    up(&smbus_piix4_sem); 
     301    return -1;  
     302  } 
     303 
     304  if ((read_write == SMBUS_WRITE) || (size == SMBUS_QUICK)) { 
     305    up(&smbus_piix4_sem); 
     306    return 0; 
     307  } 
     308 
    57309 
    58310 
     
    62314  printk("piix4.o version %s (%s)\n",LM_VERSION,LM_DATE); 
    63315#ifdef DEBUG 
     316/* PE- It might be good to make this a permanent part of the code! */ 
    64317  if (piix4_initialized) { 
    65318    printk("piix4.o: Oops, piix4_init called a second time!\n"); 
     
    97350      return res; 
    98351    } else 
    99       piix4_initialized--; 
     352      piix4_initialized=0; 
    100353  } 
    101354  if (piix4_initialized >= 1) { 
    102     /* Undo anything piix4_setup did */ 
    103     piix4_initialized--; 
     355    if (piix4_initialized) { 
     356                release_region(PIIX4_smba, 8); 
     357                piix4_initialized=0; 
     358    } 
    104359  } 
    105360  return 0; 
     
    108363#ifdef MODULE 
    109364 
    110 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 
     365MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>"); 
    111366MODULE_DESCRIPTION("PIIX4 SMBus driver"); 
    112367