Topcliff PHUB: Generate PacketHub driver
Subsystems (4)
Hi, Arnd and Yong Y
I have released Phub patch file.
Please confirm below.
Thanks, Ohtake.
--- drivers/char/Kconfig | 12 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 7 + drivers/char/pch_phub/pch_phub.c | 937 +++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 58 ++ 5 files changed, 1016 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
drivers/char/Kconfig +12 -0
@@ -4,6 +4,18 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + If you say yes to this option, support will be included for the + PCH Packet Hub Host controller. + This driver is for PCH Packet hub driver for Topcliff. + This driver is integrated as built-in. + This driver can access GbE MAC address. + This driver can access HW register. + You can also be integrated as module. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +ifeq ($(CONFIG_PHUB_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif + +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +937 -0
937 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +58 -0
58 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Hi Arnd and Yong Y
We have updated phub patch about the following.
* Arnd's commnets
* Delete PCH_READ_REG/PCH_WRITE_REG
* Delete '_t' prefix
* Modify basic type
* Delete needless 'static' prefix
* Modify returned value
* Care returned value of get_user()
* Add .llseek line
* Yong Y's comments
* Applying to the latest checkpatch(2.6.35)
* Delete unused 'DEBUG' macro in Makefile
* Delete IEEE1588 lines
* Delete 'PCH_CAN_PCLK_50MHZ'
Thanks, Ohtake.
Kernel=2.6.33.1
--- drivers/char/Kconfig | 12 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 937 ++++++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 58 +++ 5 files changed, 1012 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
drivers/char/Kconfig +12 -0
@@ -4,6 +4,18 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + If you say yes to this option, support will be included for the + PCH Packet Hub Host controller. + This driver is for PCH Packet hub driver for Topcliff. + This driver is integrated as built-in. + This driver can access GbE MAC address. + This driver can access HW register. + You can also be integrated as module. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +937 -0
937 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +58 -0
58 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Quoted 18 lines · On Tue, 22 Jun 2010 19:33:34 +0900 Masayuki Ohtak <[email protected]>…
Hi Arnd and Yong Y
We have updated phub patch about the following.
* Arnd's commnets
* Delete PCH_READ_REG/PCH_WRITE_REG
* Delete '_t' prefix
* Modify basic type
* Delete needless 'static' prefix
* Modify returned value
* Care returned value ofget_user()
* Add .llseek line* Yong Y's comments
* Applying to the latest checkpatch(2.6.35)
* Delete unused 'DEBUG' macro inMakefile
* Delete IEEE1588 lines
* Delete 'PCH_CAN_PCLK_50MHZ'
Quoted 4 lines
Thanks, Ohtake.
Kernel=2.6.33.1
Signed-off-by Masayuki Ohtake <[email protected]>
Please prepare a proper changelog for the patch - one which is suitabe for inclusion in the kernel's permanent git record. Include that changelog with each version of the patch, perhaps after alterations.
Please describe the module parameters in that changelog. Please describe the major/minor number handling within the changelog - permitting the major number to be specified on the modprobe command line is unusual and should be fully described and justified, please.
Please ensure that the changelog tells us what the driver actually does! I don't even know what a "PCH packet hub" _is_ :(
drivers/char/pch_phub/pch_phub.c line 6
Quoted 12 lines
...
drivers/char/pch_phub/pch_phub.c new file +6
-0@@ -0,0 +1,937 @@ +/*! +* @file pch_phub.c +* @brief Provides all the implementation of the interfaces pertaining to +* the Packet Hub module. +* @version 1.0.0.0 +* @section
This appears to use a markup format whcih the kernel doesn't implement.
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +12
-0+* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
drivers/char/pch_phub/pch_phub.c
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +7
-0+*/ +/** pch_phub_read_modify_write_reg - Implements the functionality of reading, +* modifying and writing register. +* @reg_addr_offset: Contains the register offset address value +* @data: Contains the writing value +* @mask: Contains the mask value +*/
kerneldoc comments are usually formatted as
/**
* foo() - do something
* @arg1 ...
I don't know whether the layout whcih this driver uses will be properly handled by the kerneldoc tools, but I'd suggest that it all be converted to the more usual style for consistency.
drivers/char/pch_phub/pch_phub.c line 142
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +12
-0+static void pch_phub_read_modify_write_reg (unsigned int reg_addr_offset, +unsigned int data,unsigned int mask) +{ + void __iomem *reg_addr = pch_phub_reg.pch_phub_base_address +\ + reg_addr_offset; +iowrite32 (((ioread32 (reg_addr) & ~mask)) | data, reg_addr); +return ; +} + + +/** pch_phub_save_reg_conf - saves register configuration +*/
The driver has quite a lot of comments which use the kerneldoc toke "/**" but which don't really look like they wre intended to be kerneldoc comments. So I'd suggest converting these to plain old comments:
/*
* pch_phub_save_reg_conf - saves register configuration */
or
/* pch_phub_save_reg_conf - saves register configuration */
or finish off the kerneldoc work by documenting the arguments (and the return values, please).
Quoted 25 lines
drivers/char/pch_phub/pch_phub.c new file +25
-0+static void pch_phub_save_reg_conf (struct pci_dev *pdev) +{ +unsigned int i =0 ; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf ENTRY\n" ); +/* to store contents of PHUB_ID register */ + pch_phub_reg.phub_id_reg =ioread32 (p +PCH_PHUB_PHUB_ID_REG ); +/* to store contents of QUEUE_PRI_VAL register */ + pch_phub_reg.q_pri_val_reg =ioread32 (p +PCH_PHUB_QUEUE_PRI_VAL_REG ); +/* to store contents of RC_QUEUE_MAXSIZE register */ + pch_phub_reg.rc_q_maxsize_reg = +ioread32 (p +PCH_PHUB_RC_QUEUE_MAXSIZE_REG ); +/* to store contents of BRI_QUEUE_MAXSIZE register */ + pch_phub_reg.bri_q_maxsize_reg = +ioread32 (p +PCH_PHUB_BRI_QUEUE_MAXSIZE_REG ); +/* to store contents of COMP_RESP_TIMEOUT register */ + pch_phub_reg.comp_resp_timeout_reg = +ioread32 (p +PCH_PHUB_COMP_RESP_TIMEOUT_REG ); +/* to store contents of BUS_SLAVE_CONTROL_REG register */ + pch_phub_reg.bus_slave_control_reg = +ioread32 (p +PCH_PHUB_BUS_SLAVE_CONTROL_REG ); +/* to store contents of DEADLOCK_AVOID_TYPE register */ + pch_phub_reg.deadlock_avoid_type_reg = +ioread32 (p +PCH_PHUB_DEADLOCK_AVOID_TYPE_REG );
drivers/char/pch_phub/pch_phub.c line 177
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+/* to store contents of INTPIN_REG_WPERMIT register 0 */ + pch_phub_reg.intpin_reg_wpermit_reg0 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG0 ); +/* to store contents of INTPIN_REG_WPERMIT register 1 */ + pch_phub_reg.intpin_reg_wpermit_reg1 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG1 ); +/* to store contents of INTPIN_REG_WPERMIT register 2 */ + pch_phub_reg.intpin_reg_wpermit_reg2 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG2 ); +/* to store contents of INTPIN_REG_WPERMIT register 3 */
s/to //g
Quoted 103 lines
drivers/char/pch_phub/pch_phub.c new file +100
-0+ pch_phub_reg.intpin_reg_wpermit_reg3 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG3 ); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.phub_id_reg=%x, " +"pch_phub_reg.q_pri_val_reg=%x, " +"pch_phub_reg.rc_q_maxsize_reg=%x, " +"pch_phub_reg.bri_q_maxsize_reg=%x, " +"pch_phub_reg.comp_resp_timeout_reg=%x, " +"pch_phub_reg.bus_slave_control_reg=%x, " +"pch_phub_reg.deadlock_avoid_type_reg=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg0=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg1=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg2=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n" , + pch_phub_reg.phub_id_reg, + pch_phub_reg.q_pri_val_reg, + pch_phub_reg.rc_q_maxsize_reg, + pch_phub_reg.bri_q_maxsize_reg, + pch_phub_reg.comp_resp_timeout_reg, + pch_phub_reg.bus_slave_control_reg, + pch_phub_reg.deadlock_avoid_type_reg, + pch_phub_reg.intpin_reg_wpermit_reg0, + pch_phub_reg.intpin_reg_wpermit_reg1, + pch_phub_reg.intpin_reg_wpermit_reg2, + pch_phub_reg.intpin_reg_wpermit_reg3); +/* to store contents of INT_REDUCE_CONTROL registers */ +for (i =0 ; i <MAX_NUM_INT_REDUCE_CONTROL_REG ; i++) { + pch_phub_reg.int_reduce_control_reg[i] = +ioread32 (p + +PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE +4 * i); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.int_reduce_control_reg[%d]=%x\n" , + i, pch_phub_reg.int_reduce_control_reg[i]); + } +/* save clk cfg register */ + pch_phub_reg.clkcfg_reg =ioread32 (p +CLKCFG_REG_OFFSET ); + +return ; +} + +static void pch_phub_restore_reg_conf (struct pci_dev *pdev) +{ +unsigned int i; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_restore_reg_conf ENTRY\n" ); +/* to store contents of PHUB_ID register */ +iowrite32 (pch_phub_reg.phub_id_reg, p +PCH_PHUB_PHUB_ID_REG ); +/* to store contents of QUEUE_PRI_VAL register */ +iowrite32 (pch_phub_reg.q_pri_val_reg, p +PCH_PHUB_QUEUE_PRI_VAL_REG ); +/* to store contents of RC_QUEUE_MAXSIZE register */ +iowrite32 (pch_phub_reg.rc_q_maxsize_reg, + p +PCH_PHUB_RC_QUEUE_MAXSIZE_REG ); +/* to store contents of BRI_QUEUE_MAXSIZE register */ +iowrite32 (pch_phub_reg.bri_q_maxsize_reg, + p +PCH_PHUB_BRI_QUEUE_MAXSIZE_REG ); +/* to store contents of COMP_RESP_TIMEOUT register */ +iowrite32 (pch_phub_reg.comp_resp_timeout_reg, + p +PCH_PHUB_COMP_RESP_TIMEOUT_REG ); +/* to store contents of BUS_SLAVE_CONTROL_REG register */ +iowrite32 (pch_phub_reg.bus_slave_control_reg, + p +PCH_PHUB_BUS_SLAVE_CONTROL_REG ); +/* to store contents of DEADLOCK_AVOID_TYPE register */ +iowrite32 (pch_phub_reg.deadlock_avoid_type_reg, + p +PCH_PHUB_DEADLOCK_AVOID_TYPE_REG ); +/* to store contents of INTPIN_REG_WPERMIT register 0 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg0, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG0 ); +/* to store contents of INTPIN_REG_WPERMIT register 1 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg1, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG1 ); +/* to store contents of INTPIN_REG_WPERMIT register 2 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg2, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG2 ); +/* to store contents of INTPIN_REG_WPERMIT register 3 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg3, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG3 ); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.phub_id_reg=%x, " +"pch_phub_reg.q_pri_val_reg=%x, " +"pch_phub_reg.rc_q_maxsize_reg=%x, " +"pch_phub_reg.bri_q_maxsize_reg=%x, " +"pch_phub_reg.comp_resp_timeout_reg=%x, " +"pch_phub_reg.bus_slave_control_reg=%x, " +"pch_phub_reg.deadlock_avoid_type_reg=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg0=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg1=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg2=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n" , + pch_phub_reg.phub_id_reg, + pch_phub_reg.q_pri_val_reg, + pch_phub_reg.rc_q_maxsize_reg, + pch_phub_reg.bri_q_maxsize_reg, + pch_phub_reg.comp_resp_timeout_reg, + pch_phub_reg.bus_slave_control_reg, + pch_phub_reg.deadlock_avoid_type_reg, + pch_phub_reg.intpin_reg_wpermit_reg0, + pch_phub_reg.intpin_reg_wpermit_reg1, + pch_phub_reg.intpin_reg_wpermit_reg2, + pch_phub_reg.intpin_reg_wpermit_reg3);
drivers/char/pch_phub/pch_phub.c line 290
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+/* to store contents of INT_REDUCE_CONTROL register */ +for (i =0 ; i <MAX_NUM_INT_REDUCE_CONTROL_REG ; i++) { +iowrite32 (pch_phub_reg.int_reduce_control_reg[i], + p +PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE +4 * i); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.int_reduce_control_reg[%d]=%x\n" , + i, pch_phub_reg.int_reduce_control_reg[i]); + } + +/*restore the clock config reg */
One space after the /*, please.
Quoted 5 lines
drivers/char/pch_phub/pch_phub.c new file +5
-0+iowrite32 (pch_phub_reg.clkcfg_reg, p +CLKCFG_REG_OFFSET ); + +return ; +} +
drivers/char/pch_phub/pch_phub.c line 305
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+/** pch_phub_read_serial_rom - Implements the functionality of reading Serial +* ROM. +* @offset_address: Contains the Serial ROM address offset value +* @data: Contains the Serial ROM value +*/ +static int pch_phub_read_serial_rom (unsigned int offset_address, +unsigned char *data) +{ + void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + offset_address;
Unneeded \. There are several instances of this in the driver.
drivers/char/pch_phub/pch_phub.c line 313
Quoted 7 lines
drivers/char/pch_phub/pch_phub.c new file +7
-0+ *data =ioread8 (mem_addr); + +return 0 ; +} + +/** pch_phub_write_serial_rom - Implements the functionality of writing Serial +* ROM.
Strange layout. I don't know what this will look like after kerneldoc processing - it might make a mess. Conventional layout is
/**
* pch_phub_write_serial_rom - Implements the functionality of writing Serial ROM.
or
/**
* pch_phub_write_serial_rom - Implements the functionality of writing Serial
* ROM.
(there are several instances of this).
Quoted 7 lines
+ * @offset_address: Contains the Serial ROM address offset value
+ * @data: Contains the Serial ROM value
+ */drivers/char/pch_phub/pch_phub.c new file +4
-0+static int pch_phub_write_serial_rom (unsigned int offset_address, +unsigned char data) +{ +int retval =0 ;
drivers/char/pch_phub/pch_phub.c line 330
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + (offset_address &0xFFFFFFFC ); +int i =0 ; +unsigned int word_data =0 ; + +iowrite32 (PCH_PHUB_ROM_WRITE_ENABLE , + pch_phub_reg.pch_phub_extrom_base_address +\ +PHUB_CONTROL ); + + word_data =ioread32 (mem_addr);
The driver tends to do
int foo = 0; ... foo = ...
in quite a lot of places. The initialisation to zero is harmless - the compiler will take it out again. But it's unusual and jsut adds noise.
The compiler will warn about use of uninitialised variables anyway. In fact this unnecessary initalisation will suppress compiler warnings which might have revealed real bugs. I'd suggest that they all be removed (there are quite a lot in this driver).
Quoted 47 lines
drivers/char/pch_phub/pch_phub.c new file +44
-0+switch (offset_address %4 ) { +case 0 : + word_data &=0xFFFFFF00 ; +iowrite32 ((word_data | (unsigned int )data), + mem_addr); +break ; +case 1 : + word_data &=0xFFFF00FF ; +iowrite32 ((word_data | ((unsigned int )data <<8 )), + mem_addr); +break ; +case 2 : + word_data &=0xFF00FFFF ; +iowrite32 ((word_data | ((unsigned int )data <<16 )), + mem_addr); +break ; +case 3 : + word_data &=0x00FFFFFF ; +iowrite32 ((word_data | ((unsigned int )data <<24 )), + mem_addr); +break ; + } +while (0x00 != +ioread8 (pch_phub_reg.pch_phub_extrom_base_address +\ +PHUB_STATUS )) { +msleep (1 ); +if (PHUB_TIMEOUT == i) { + retval = -EPERM ; +break ; + } + i++; + } + +iowrite32 (PCH_PHUB_ROM_WRITE_DISABLE , + pch_phub_reg.pch_phub_extrom_base_address +\ +PHUB_CONTROL ); + +return retval; +} + +static ssize_t pch_phub_read (struct file *file,char __user *buf,size_t size, +loff_t *ppos) +{ +unsigned int rom_signature =0 ;
drivers/char/pch_phub/pch_phub.c
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+unsigned char rom_length; +int ret_value; +unsigned int tmp; +unsigned char data; +unsigned int addr_offset =0 ; +unsigned int orom_size; +loff_t pos = *ppos; + +if (pos <0 ) +return -EINVAL ;
I think vfs_read() -> rw_verify_area() already did that, so indovidual ->read() implementations don't need to check for negative offset.
drivers/char/pch_phub/pch_phub.c line 501
Quoted 1 line
drivers/char/pch_phub/pch_phub.c new file +1
-0+/*Get Rom signature*/
Spaces after /* and before */, please.
Quoted 14 lines
drivers/char/pch_phub/pch_phub.c new file +14
-0+pch_phub_read_serial_rom (0x80 , (unsigned char *)&rom_signature); +pch_phub_read_serial_rom (0x81 , (unsigned char *)&tmp); + rom_signature |= (tmp &0xff ) <<8 ; +if (rom_signature ==0xAA55 ) { +pch_phub_read_serial_rom (0x82 , &rom_length); + orom_size = rom_length *512 ; +if (orom_size < pos) +return 0 ; + +for (addr_offset =0 ; addr_offset < size; addr_offset++) { +pch_phub_read_serial_rom (0x80 + addr_offset + pos, + &data); + ret_value =copy_to_user (&buf[addr_offset], &data,1 ); +if (ret_value)
drivers/char/pch_phub/pch_phub.c line 525
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+return -EFAULT ; + +if (orom_size < pos + addr_offset) { + *ppos += addr_offset; +return addr_offset; + } + + } + }else { +return -ENOEXEC ;
ENOEXEC means "your executable file doesn't have suitable contents". If this error gets propagated to userspace the poor user will be wondering who corrupted his ELF files and would be surprised to find out that the error in fact came from his packethub driver.
So please use a more appropriate errno here.
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +12
-0+ } + *ppos += addr_offset; +return addr_offset; +} + +/** pch_phub_write - Implements the write functionality of the Packet Hub +* module. +* @file: Contains the reference of the file structure +* @buf: Usermode buffer pointer +* @size: Usermode buffer size +* @ppos: Contains the reference of the file structure +*/
drivers/char/pch_phub/pch_phub.c line 547
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+static ssize_t pch_phub_write (struct file *file,const char __user *buf, +size_t size,loff_t *ppos) +{ +unsigned int data; +int ret_value; +unsigned int addr_offset =0 ; +loff_t pos = *ppos; + +if (pos <0 ) +return -EINVAL ;
vfs_write() already did that.
drivers/char/pch_phub/pch_phub.c line 557
Quoted 9 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+for (addr_offset =0 ; addr_offset < size; addr_offset++) { + ret_value =get_user (data, &buf[addr_offset]); +if (ret_value) +return -EFAULT ; + + ret_value =pch_phub_write_serial_rom (0x80 + addr_offset + pos, + data); +if (ret_value) +return -EIO ;
This overwrites the pch_phub_write_serial_rom() return value. it's generally better to propagate error return values instead of replacing them with different ones.
otoh pch_phub_write_serial_rom() can return -EPERM. "Operation not permitted. An attempt was made to perform an operation limited to processes with appropriate privileges or to the owner of a file or other resource.". That doesn't sound like an appropriate errno for a driver to use?
Quoted 25 lines
drivers/char/pch_phub/pch_phub.c new file +25
-0+if (PCH_PHUB_OROM_SIZE < pos + addr_offset) { + *ppos += addr_offset; +return addr_offset; + } + + } + + *ppos += addr_offset; +return addr_offset; +} + + +/** pch_phub_ioctl - Implements the various ioctl functionalities of the Packet +* Hub module. +* @inode: Contains the reference of the inode structure +* @file: Contains the reference of the file structure +* @cmd: Contains the command value +* @arg: Contains the command argument value +*/ + + +static long pch_phub_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +int ret_value =0 ;
drivers/char/pch_phub/pch_phub.c line 593
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+__u8 mac_addr[6 ]; +int ret; +unsigned int i; +void __user *varg = (void __user *)arg; + + ret =mutex_lock_interruptible (&pch_phub_ioctl_mutex); +if (ret) { + ret_value = -ERESTARTSYS ; + goto return_nomutex; + }
A plain old `return -ERESTARTSYS' is OK here.
drivers/char/pch_phub/pch_phub.c line 596
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+if (pch_phub_reg.pch_phub_suspended == true) { + ret_value = -EPERM ;
EPERM?
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+ goto return_ioctrl; + } + +switch (cmd) {
drivers/char/pch_phub/pch_phub.c line 610
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+case IOCTL_PHUB_READ_MAC_ADDR : +for (i =0 ; i <6 ; i++) +pch_phub_read_gbe_mac_addr (i, &mac_addr[i]); + + ret_value =copy_to_user (varg, + mac_addr,sizeof (mac_addr)); +if (ret_value) { + ret_value = -EFAULT ; + goto return_ioctrl; + }
The goto is unneeded.
drivers/char/pch_phub/pch_phub.c line 619
Quoted 9 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+break ; + +case IOCTL_PHUB_WRITE_MAC_ADDR : + ret_value =copy_from_user (mac_addr, varg,sizeof (mac_addr)); + +if (ret_value) { + ret_value = -EFAULT ; + goto return_ioctrl; + }
Could do a `break'.
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+for (i =0 ; i <6 ; i++) +pch_phub_write_gbe_mac_addr (i, mac_addr[i]); +break ; + +default : + ret_value = -EINVAL ; +break ; + }
drivers/char/pch_phub/pch_phub.c line 637
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+return_ioctrl: +mutex_unlock (&pch_phub_ioctl_mutex); +return_nomutex: +return ret_value; +} + + +/** +* file_operations structure initialization +*/
That's not a kerneldoc comment, but it has the /** kerneldoc token.
Quoted 7 lines
drivers/char/pch_phub/pch_phub.c new file +7
-0+static const struct file_operations pch_phub_fops = { + .owner =THIS_MODULE , + .read = pch_phub_read, + .write = pch_phub_write, + .unlocked_ioctl = pch_phub_ioctl, + .llseek = default_llseek +};
drivers/char/pch_phub/pch_phub.c line 654
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ + +/** pch_phub_probe - Implements the probe functionality of the module. +* @pdev: Contains the reference of the pci_dev structure +* @id: Contains the reference of the pci_device_id structure +*/ +static int __devinit pch_phub_probe (struct pci_dev *pdev, +const struct pci_device_id *id) +{ +char *DRIVER_NAME ="pch_phub" ;
hm, why was that upper case?
Maybe use MODULE_NAME instead? Or
static const char driver_name[] = "pch_phub";
drivers/char/pch_phub/pch_phub.c line 659
Quoted 5 lines
drivers/char/pch_phub/pch_phub.c new file +5
-0+int ret; +unsigned int rom_size; + + pch_phub_major_no = (pch_phub_major_no <0 || pch_phub_major_no >254 ) ? +0 : pch_phub_major_no;
This looks odd - should be explained in code comments and/or changelog.
Quoted 11 lines
drivers/char/pch_phub/pch_phub.c new file +11
-0+ ret =pci_enable_device (pdev); +if (ret) { +dev_dbg (&pdev->dev, +"\npch_phub_probe : pci_enable_device FAILED" ); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_enable_device returns %d\n" , ret); + + ret =pci_request_regions (pdev,DRIVER_NAME ); +if (ret) {
drivers/char/pch_phub/pch_phub.c line 681
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+dev_dbg (&pdev->dev, +"pch_phub_probe : pci_request_regions FAILED" ); +pci_disable_device (pdev); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_request_regions returns %d\n" , ret); + + pch_phub_reg.pch_phub_base_address = \ + (void __iomem *)pci_iomap(pdev, 1, 0);
Unneeded and undesirable typeast.
drivers/char/pch_phub/pch_phub.c line 695
Quoted 13 lines
drivers/char/pch_phub/pch_phub.c new file +13
-0+if (pch_phub_reg.pch_phub_base_address ==0 ) { +dev_dbg (&pdev->dev,"pch_phub_probe : pci_iomap FAILED" ); +pci_release_regions (pdev); +pci_disable_device (pdev); + ret = -ENOMEM ; + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : pci_iomap SUCCESS and value " +"in pch_phub_base_address variable is 0x%08x\n" , + (unsigned int )pch_phub_reg.pch_phub_base_address); + + pch_phub_reg.pch_phub_extrom_base_address = + (void __iomem *)pci_map_rom (pdev, &rom_size);
Ditto
drivers/char/pch_phub/pch_phub.c line 700
Quoted 5 lines
drivers/char/pch_phub/pch_phub.c new file +5
-0+if (pch_phub_reg.pch_phub_extrom_base_address ==0 ) { +dev_dbg (&pdev->dev,"pch_phub_probe : pci_map_rom FAILED" ); +pci_iounmap (pdev, (void *)pch_phub_reg.pch_phub_base_address); +pci_release_regions (pdev); +pci_disable_device (pdev);
This is getting painful. I'd suggest removal of the duplicated code via the standard `goto out_iounmap' unwinding approach.
Quoted 9 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+ ret = -ENOMEM ; + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_map_rom SUCCESS and value in " +"pch_phub_extrom_base_address variable is 0x%08x\n" , + (unsigned int )pch_phub_reg.pch_phub_extrom_base_address); + +if (pch_phub_major_no) {
drivers/char/pch_phub/pch_phub.c line 719
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ pch_phub_dev_no =MKDEV (pch_phub_major_no,0 ); + ret =register_chrdev_region (pch_phub_dev_no, +PCH_MINOR_NOS ,DRIVER_NAME ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : " +"register_chrdev_region FAILED" ); +pci_unmap_rom (pdev, + (void *)pch_phub_reg.pch_phub_extrom_base_address); +pci_iounmap (pdev, + (void *)pch_phub_reg.pch_phub_base_address);
More unneeded typecasts.
Quoted 6 lines
drivers/char/pch_phub/pch_phub.c new file +6
-0+pci_release_regions (pdev); +pci_disable_device (pdev); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"register_chrdev_region returns %d\n" , ret);
drivers/char/pch_phub/pch_phub.c line 735
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ }else { + ret =alloc_chrdev_region (&pch_phub_dev_no,0 , +PCH_MINOR_NOS ,DRIVER_NAME ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : " +"alloc_chrdev_region FAILED" ); +pci_unmap_rom (pdev, + (void *)pch_phub_reg.pch_phub_extrom_base_address); +pci_iounmap (pdev, + (void *)pch_phub_reg.pch_phub_base_address);
more..
Quoted 118 lines
drivers/char/pch_phub/pch_phub.c new file +115
-0+pci_release_regions (pdev); +pci_disable_device (pdev); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"alloc_chrdev_region returns %d\n" , ret); + } + +cdev_init (&pch_phub_dev, &pch_phub_fops); +dev_dbg (&pdev->dev, +"pch_phub_probe : cdev_init invoked successfully\n" ); + + pch_phub_dev.owner =THIS_MODULE ; + pch_phub_dev.ops = &pch_phub_fops; + + ret =cdev_add (&pch_phub_dev, pch_phub_dev_no,PCH_MINOR_NOS ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : cdev_add FAILED" ); +unregister_chrdev_region (pch_phub_dev_no,PCH_MINOR_NOS ); +pci_unmap_rom (pdev, + (void *)pch_phub_reg.pch_phub_extrom_base_address); +pci_iounmap (pdev, (void *)pch_phub_reg.pch_phub_base_address); +pci_release_regions (pdev); +pci_disable_device (pdev); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : cdev_add returns %d\n" , ret); + +/*set the clock config reg if CAN clock is 50Mhz */ +dev_dbg (&pdev->dev,"pch_phub_probe : invoking " +"pch_phub_read_modify_write_reg " +"to set CLKCFG reg for CAN clk 50Mhz\n" ); +pch_phub_read_modify_write_reg ((unsigned int )CLKCFG_REG_OFFSET , +CLKCFG_CAN_50MHZ ,CLKCFG_CANCLK_MASK ); + +/* set the prefech value */ +iowrite32 (0x000ffffa , pch_phub_reg.pch_phub_base_address +0x14 ); +/* set the interrupt delay value */ +iowrite32 (0x25 , pch_phub_reg.pch_phub_base_address +0x44 ); +return 0 ; + +err_probe: +dev_dbg (&pdev->dev,"pch_phub_probe returns %d\n" , ret); +return ret; +} + +#ifdef CONFIG_PM + +/** pch_phub_suspend - Implements the suspend functionality of the module. +* @pdev: Contains the reference of the pci_dev structure +* @state: Contains the reference of the pm_message_t structure +*/ +static int pch_phub_suspend (struct pci_dev *pdev,pm_message_t state) +{ +int ret; + + pch_phub_reg.pch_phub_suspended = true;/* For blocking further IOCTLs */ + +pch_phub_save_reg_conf (pdev); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pch_phub_save_reg_conf Invoked successfully\n" ); + + ret =pci_save_state (pdev); +if (ret) { +dev_dbg (&pdev->dev, +" pch_phub_suspend -pci_save_state returns-%d\n" , ret); +return ret; + } +dev_dbg (&pdev->dev, +"pch_phub_suspend - pci_save_state returns %d\n" , ret); +pci_enable_wake (pdev, PCI_D3hot,0 ); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pci_enable_wake Invoked successfully\n" ); + +pci_disable_device (pdev); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pci_disable_device Invoked successfully\n" ); + +pci_set_power_state (pdev,pci_choose_state (pdev, state)); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pci_set_power_state Invoked successfully " +"return = %d\n" ,0 ); + +return 0 ; +} + +/** pch_phub_resume - Implements the resume functionality of the module. +* @pdev: Contains the reference of the pci_dev structure +*/ +static int pch_phub_resume (struct pci_dev *pdev) +{ + +int ret; + +pci_set_power_state (pdev,PCI_D0 ); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_set_power_state Invoked successfully\n" ); + +pci_restore_state (pdev); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_restore_state Invoked successfully\n" ); + + ret =pci_enable_device (pdev); +if (ret) { +dev_dbg (&pdev->dev, +"pch_phub_resume-pci_enable_device failed " ); +return ret; + } + +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_enable_device returns -%d\n" , ret); + +pci_enable_wake (pdev, PCI_D3hot,0 ); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_enable_wake Invoked successfully\n" );
drivers/char/pch_phub/pch_phub.c line 891
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +pch_phub_restore_reg_conf (pdev); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pch_phub_restore_reg_conf Invoked successfully\n" ); + + pch_phub_reg.pch_phub_suspended = false; + +dev_dbg (&pdev->dev,"pch_phub_resume returns- %d\n" ,0 ); +return 0 ; +}
Here you can put
#else
#define pch_phub_suspend NULL
#define pch_phub_resume NULL
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+#endif /* CONFIG_PM */ + +static struct pci_device_id pch_phub_pcidev_id[] = { + + {PCI_DEVICE (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_PCH1_PHUB )}, + {0 ,} +}; +
drivers/char/pch_phub/pch_phub.c line 909
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +static struct pci_driver pch_phub_driver = { + .name ="pch_phub" , + .id_table = pch_phub_pcidev_id, + .probe = pch_phub_probe, + .remove =__devexit_p (pch_phub_remove), +#ifdef CONFIG_PM + .suspend = pch_phub_suspend, + .resume = pch_phub_resume +#endif
and then remove this ifdef.
drivers/char/pch_phub/pch_phub.h line 7
Quoted 13 lines
...
drivers/char/pch_phub/pch_phub.h new file +7
-0@@ -0,0 +1,58 @@ +#ifndef __PCH_PHUB_H__ +#define __PCH_PHUB_H__ +/*! +* @file pch_phub.h +* @brief Provides all the interfaces pertaining to the Packet Hub module. +* @version 1.0.0.0 +* @section
?
Quoted 17 lines
drivers/char/pch_phub/pch_phub.h new file +17
-0+* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* +* History: +* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
drivers/char/pch_phub/pch_phub.h line 34
Quoted 10 lines
drivers/char/pch_phub/pch_phub.h new file +10
-0+* +* created: +* OKI SEMICONDUCTOR 04/14/2010 +* modified: +* +*/ + +#define PHUB_IOCTL_MAGIC (0xf7) + +/*Outlines the read mac address function signature. */
Space after /*, please (check the whole patch)
drivers/char/pch_phub/pch_phub.h line 38
Quoted 4 lines
drivers/char/pch_phub/pch_phub.h new file +4
-0+#define IOCTL_PHUB_READ_MAC_ADDR (_IOR(PHUB_IOCTL_MAGIC, 6, __u8[6])) + +/*brief Outlines the write mac address function signature. */ +#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, __u8[6]))
"brief"?
I didn't notice any documentation for these ioctls anywhere?
Quoted 19 lines
drivers/char/pch_phub/pch_phub.h new file +19
-0+ +/* Registers address offset */ +#define PCH_PHUB_PHUB_ID_REG 0x0000 +#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004 +#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008 +#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C +#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010 +#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014 +#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C +#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 +#define CLKCFG_REG_OFFSET 0x500 + +#define PCH_PHUB_OROM_SIZE 15360 + +#endif
Hi Andrew
Thank you for your comments.
We will resubmit modified our patch by tomorrow or day after tomorrow at the latest.
Thanks.
Ohtake
----- Original Message -----
From: "Andrew Morton" <[email protected]>
To: "Masayuki Ohtak" <[email protected]>
Cc: "Arnd Bergmann" <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>; <[email protected]>; "Alan Cox" <[email protected]>; "LKML" <[email protected]>
Sent: Wednesday, June 23, 2010 7:12 AM
Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
Quoted 932 lines
Quoted 18 lines · On Tue, 22 Jun 2010 19:33:34 +0900 Masayuki Ohtak <[email protected]>…
Hi Arnd and Yong Y
We have updated phub patch about the following.
* Arnd's commnets
* Delete PCH_READ_REG/PCH_WRITE_REG
* Delete '_t' prefix
* Modify basic type
* Delete needless 'static' prefix
* Modify returned value
* Care returned value ofget_user()
* Add .llseek line* Yong Y's comments
* Applying to the latest checkpatch(2.6.35)
* Delete unused 'DEBUG' macro inMakefile
* Delete IEEE1588 lines
* Delete 'PCH_CAN_PCLK_50MHZ'Quoted 4 lines
Thanks, Ohtake.
Kernel=2.6.33.1
Signed-off-by Masayuki Ohtake <[email protected]>Please prepare a proper changelog for the patch - one which is suitabe for inclusion in the kernel's permanent git record. Include that changelog with each version of the patch, perhaps after alterations.
Please describe the module parameters in that changelog. Please describe the major/minor number handling within the changelog - permitting the major number to be specified on the modprobe command line is unusual and should be fully described and justified, please.
Please ensure that the changelog tells us what the driver actually does! I don't even know what a "PCH packet hub" _is_ :(
drivers/char/pch_phub/pch_phub.c line 6
Quoted 12 lines
...
drivers/char/pch_phub/pch_phub.c new file +6
-0@@ -0,0 +1,937 @@ +/*! +* @file pch_phub.c +* @brief Provides all the implementation of the interfaces pertaining to +* the Packet Hub module. +* @version 1.0.0.0 +* @section This appears to use a markup format whcih the kernel doesn't implement.
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +12
-0+* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. drivers/char/pch_phub/pch_phub.c
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +7
-0+*/ +/** pch_phub_read_modify_write_reg - Implements the functionality of reading, +* modifying and writing register. +* @reg_addr_offset: Contains the register offset address value +* @data: Contains the writing value +* @mask: Contains the mask value +*/ kerneldoc comments are usually formatted as
/**
*foo()- do something
* @arg1 ...I don't know whether the layout whcih this driver uses will be properly handled by the kerneldoc tools, but I'd suggest that it all be converted to the more usual style for consistency.
drivers/char/pch_phub/pch_phub.c line 142
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +12
-0+static void pch_phub_read_modify_write_reg (unsigned int reg_addr_offset, +unsigned int data,unsigned int mask) +{ + void __iomem *reg_addr = pch_phub_reg.pch_phub_base_address +\ + reg_addr_offset; +iowrite32 (((ioread32 (reg_addr) & ~mask)) | data, reg_addr); +return ; +} + + +/** pch_phub_save_reg_conf - saves register configuration +*/ The driver has quite a lot of comments which use the kerneldoc toke "/**" but which don't really look like they wre intended to be kerneldoc comments. So I'd suggest converting these to plain old comments:
/*
*pch_phub_save_reg_conf- saves register configuration */or
/*
pch_phub_save_reg_conf- saves register configuration */or finish off the kerneldoc work by documenting the arguments (and the return values, please).
Quoted 25 lines
drivers/char/pch_phub/pch_phub.c new file +25
-0+static void pch_phub_save_reg_conf (struct pci_dev *pdev) +{ +unsigned int i =0 ; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf ENTRY\n" ); +/* to store contents of PHUB_ID register */ + pch_phub_reg.phub_id_reg =ioread32 (p +PCH_PHUB_PHUB_ID_REG ); +/* to store contents of QUEUE_PRI_VAL register */ + pch_phub_reg.q_pri_val_reg =ioread32 (p +PCH_PHUB_QUEUE_PRI_VAL_REG ); +/* to store contents of RC_QUEUE_MAXSIZE register */ + pch_phub_reg.rc_q_maxsize_reg = +ioread32 (p +PCH_PHUB_RC_QUEUE_MAXSIZE_REG ); +/* to store contents of BRI_QUEUE_MAXSIZE register */ + pch_phub_reg.bri_q_maxsize_reg = +ioread32 (p +PCH_PHUB_BRI_QUEUE_MAXSIZE_REG ); +/* to store contents of COMP_RESP_TIMEOUT register */ + pch_phub_reg.comp_resp_timeout_reg = +ioread32 (p +PCH_PHUB_COMP_RESP_TIMEOUT_REG ); +/* to store contents of BUS_SLAVE_CONTROL_REG register */ + pch_phub_reg.bus_slave_control_reg = +ioread32 (p +PCH_PHUB_BUS_SLAVE_CONTROL_REG ); +/* to store contents of DEADLOCK_AVOID_TYPE register */ + pch_phub_reg.deadlock_avoid_type_reg = +ioread32 (p +PCH_PHUB_DEADLOCK_AVOID_TYPE_REG );drivers/char/pch_phub/pch_phub.c line 177
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+/* to store contents of INTPIN_REG_WPERMIT register 0 */ + pch_phub_reg.intpin_reg_wpermit_reg0 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG0 ); +/* to store contents of INTPIN_REG_WPERMIT register 1 */ + pch_phub_reg.intpin_reg_wpermit_reg1 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG1 ); +/* to store contents of INTPIN_REG_WPERMIT register 2 */ + pch_phub_reg.intpin_reg_wpermit_reg2 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG2 ); +/* to store contents of INTPIN_REG_WPERMIT register 3 */ s/to //g
Quoted 103 lines
+ pch_phub_reg.intpin_reg_wpermit_reg3 =
drivers/char/pch_phub/pch_phub.c new file +99
-0+ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG3 ); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.phub_id_reg=%x, " +"pch_phub_reg.q_pri_val_reg=%x, " +"pch_phub_reg.rc_q_maxsize_reg=%x, " +"pch_phub_reg.bri_q_maxsize_reg=%x, " +"pch_phub_reg.comp_resp_timeout_reg=%x, " +"pch_phub_reg.bus_slave_control_reg=%x, " +"pch_phub_reg.deadlock_avoid_type_reg=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg0=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg1=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg2=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n" , + pch_phub_reg.phub_id_reg, + pch_phub_reg.q_pri_val_reg, + pch_phub_reg.rc_q_maxsize_reg, + pch_phub_reg.bri_q_maxsize_reg, + pch_phub_reg.comp_resp_timeout_reg, + pch_phub_reg.bus_slave_control_reg, + pch_phub_reg.deadlock_avoid_type_reg, + pch_phub_reg.intpin_reg_wpermit_reg0, + pch_phub_reg.intpin_reg_wpermit_reg1, + pch_phub_reg.intpin_reg_wpermit_reg2, + pch_phub_reg.intpin_reg_wpermit_reg3); +/* to store contents of INT_REDUCE_CONTROL registers */ +for (i =0 ; i <MAX_NUM_INT_REDUCE_CONTROL_REG ; i++) { + pch_phub_reg.int_reduce_control_reg[i] = +ioread32 (p + +PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE +4 * i); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.int_reduce_control_reg[%d]=%x\n" , + i, pch_phub_reg.int_reduce_control_reg[i]); + } +/* save clk cfg register */ + pch_phub_reg.clkcfg_reg =ioread32 (p +CLKCFG_REG_OFFSET ); + +return ; +} + +static void pch_phub_restore_reg_conf (struct pci_dev *pdev) +{ +unsigned int i; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_restore_reg_conf ENTRY\n" ); +/* to store contents of PHUB_ID register */ +iowrite32 (pch_phub_reg.phub_id_reg, p +PCH_PHUB_PHUB_ID_REG ); +/* to store contents of QUEUE_PRI_VAL register */ +iowrite32 (pch_phub_reg.q_pri_val_reg, p +PCH_PHUB_QUEUE_PRI_VAL_REG ); +/* to store contents of RC_QUEUE_MAXSIZE register */ +iowrite32 (pch_phub_reg.rc_q_maxsize_reg, + p +PCH_PHUB_RC_QUEUE_MAXSIZE_REG ); +/* to store contents of BRI_QUEUE_MAXSIZE register */ +iowrite32 (pch_phub_reg.bri_q_maxsize_reg, + p +PCH_PHUB_BRI_QUEUE_MAXSIZE_REG ); +/* to store contents of COMP_RESP_TIMEOUT register */ +iowrite32 (pch_phub_reg.comp_resp_timeout_reg, + p +PCH_PHUB_COMP_RESP_TIMEOUT_REG ); +/* to store contents of BUS_SLAVE_CONTROL_REG register */ +iowrite32 (pch_phub_reg.bus_slave_control_reg, + p +PCH_PHUB_BUS_SLAVE_CONTROL_REG ); +/* to store contents of DEADLOCK_AVOID_TYPE register */ +iowrite32 (pch_phub_reg.deadlock_avoid_type_reg, + p +PCH_PHUB_DEADLOCK_AVOID_TYPE_REG ); +/* to store contents of INTPIN_REG_WPERMIT register 0 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg0, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG0 ); +/* to store contents of INTPIN_REG_WPERMIT register 1 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg1, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG1 ); +/* to store contents of INTPIN_REG_WPERMIT register 2 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg2, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG2 ); +/* to store contents of INTPIN_REG_WPERMIT register 3 */ +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg3, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG3 ); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.phub_id_reg=%x, " +"pch_phub_reg.q_pri_val_reg=%x, " +"pch_phub_reg.rc_q_maxsize_reg=%x, " +"pch_phub_reg.bri_q_maxsize_reg=%x, " +"pch_phub_reg.comp_resp_timeout_reg=%x, " +"pch_phub_reg.bus_slave_control_reg=%x, " +"pch_phub_reg.deadlock_avoid_type_reg=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg0=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg1=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg2=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n" , + pch_phub_reg.phub_id_reg, + pch_phub_reg.q_pri_val_reg, + pch_phub_reg.rc_q_maxsize_reg, + pch_phub_reg.bri_q_maxsize_reg, + pch_phub_reg.comp_resp_timeout_reg, + pch_phub_reg.bus_slave_control_reg, + pch_phub_reg.deadlock_avoid_type_reg, + pch_phub_reg.intpin_reg_wpermit_reg0, + pch_phub_reg.intpin_reg_wpermit_reg1, + pch_phub_reg.intpin_reg_wpermit_reg2, + pch_phub_reg.intpin_reg_wpermit_reg3);drivers/char/pch_phub/pch_phub.c line 290
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+/* to store contents of INT_REDUCE_CONTROL register */ +for (i =0 ; i <MAX_NUM_INT_REDUCE_CONTROL_REG ; i++) { +iowrite32 (pch_phub_reg.int_reduce_control_reg[i], + p +PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE +4 * i); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.int_reduce_control_reg[%d]=%x\n" , + i, pch_phub_reg.int_reduce_control_reg[i]); + } + +/*restore the clock config reg */ One space after the /*, please.
Quoted 5 lines
+
iowrite32(pch_phub_reg.clkcfg_reg, p + CLKCFG_REG_OFFSET);drivers/char/pch_phub/pch_phub.c new file +4
-0+ +return ; +} +drivers/char/pch_phub/pch_phub.c line 305
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+/** pch_phub_read_serial_rom - Implements the functionality of reading Serial +* ROM. +* @offset_address: Contains the Serial ROM address offset value +* @data: Contains the Serial ROM value +*/ +static int pch_phub_read_serial_rom (unsigned int offset_address, +unsigned char *data) +{ + void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + offset_address;Unneeded \. There are several instances of this in the driver.
drivers/char/pch_phub/pch_phub.c line 313
Quoted 7 lines
+ *data =
ioread8(mem_addr);drivers/char/pch_phub/pch_phub.c new file +6
-0+ +return 0 ; +} + +/** pch_phub_write_serial_rom - Implements the functionality of writing Serial +* ROM. Strange layout. I don't know what this will look like after kerneldoc processing - it might make a mess. Conventional layout is
/**
*pch_phub_write_serial_rom- Implements the functionality of writing Serial ROM.or
/**
*pch_phub_write_serial_rom- Implements the functionality of writing Serial
* ROM.(there are several instances of this).
Quoted 7 lines
+ * @offset_address: Contains the Serial ROM address offset value
+ * @data: Contains the Serial ROM value
+ */drivers/char/pch_phub/pch_phub.c new file +4
-0+static int pch_phub_write_serial_rom (unsigned int offset_address, +unsigned char data) +{ +int retval =0 ;drivers/char/pch_phub/pch_phub.c line 330
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + (offset_address &0xFFFFFFFC ); +int i =0 ; +unsigned int word_data =0 ; + +iowrite32 (PCH_PHUB_ROM_WRITE_ENABLE , + pch_phub_reg.pch_phub_extrom_base_address +\ +PHUB_CONTROL ); + + word_data =ioread32 (mem_addr);The driver tends to do
int foo = 0;
...
foo = ...
in quite a lot of places. The initialisation to zero is harmless - the compiler will take it out again. But it's unusual and jsut adds noise.
The compiler will warn about use of uninitialised variables anyway. In fact this unnecessary initalisation will suppress compiler warnings which might have revealed real bugs. I'd suggest that they all be removed (there are quite a lot in this driver).
Quoted 47 lines
+ switch (
offset_address% 4) {
+ case 0:
+word_data&=0xFFFFFF00;
+ iowrite32((word_data | (unsigned int)data),
+mem_addr);
+ break;
+ case 1:
+word_data&=0xFFFF00FF;
+ iowrite32((word_data | ((unsigned int)data << 8)),
+mem_addr);
+ break;
+ case 2:
+word_data&=0xFF00FFFF;
+ iowrite32((word_data | ((unsigned int)data << 16)),
+mem_addr);
+ break;
+ case 3:
+word_data&=0x00FFFFFF;
+ iowrite32((word_data | ((unsigned int)data << 24)),
+mem_addr);
+ break;
+ }
+ while (0x00!=drivers/char/pch_phub/pch_phub.c new file +21
-0+ ioread8(pch_phub_reg.pch_phub_extrom_base_address +\ + PHUB_STATUS)) { +msleep (1 ); +if (PHUB_TIMEOUT == i) { + retval = -EPERM ; +break ; + } + i++; + } + +iowrite32 (PCH_PHUB_ROM_WRITE_DISABLE , + pch_phub_reg.pch_phub_extrom_base_address +\ +PHUB_CONTROL ); + +return retval; +} + +static ssize_t pch_phub_read (struct file *file,char __user *buf,size_t size, +loff_t *ppos) +{ +unsigned int rom_signature =0 ;drivers/char/pch_phub/pch_phub.c
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+unsigned char rom_length; +int ret_value; +unsigned int tmp; +unsigned char data; +unsigned int addr_offset =0 ; +unsigned int orom_size; +loff_t pos = *ppos; + +if (pos <0 ) +return -EINVAL ;I think
vfs_read()->rw_verify_area()already did that, so indovidual ->read() implementations don't need to check for negative offset.Quoted 1 line
+ /*Get Rom signature*/
Spaces after /* and before */, please.
Quoted 14 lines
+
pch_phub_read_serial_rom(0x80, (unsigned char *)&rom_signature);
+pch_phub_read_serial_rom(0x81, (unsigned char *)&tmp);
+rom_signature|= (tmp &0xff) << 8;
+ if (rom_signature==0xAA55) {
+pch_phub_read_serial_rom(0x82, &rom_length);
+orom_size=rom_length* 512;
+ if (orom_size< pos)
+ return 0;drivers/char/pch_phub/pch_phub.c new file +6
-0+ +for (addr_offset =0 ; addr_offset < size; addr_offset++) { +pch_phub_read_serial_rom (0x80 + addr_offset + pos, + &data); + ret_value =copy_to_user (&buf[addr_offset], &data,1 ); +if (ret_value)drivers/char/pch_phub/pch_phub.c line 525
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+return -EFAULT ; + +if (orom_size < pos + addr_offset) { + *ppos += addr_offset; +return addr_offset; + } + + } + }else { +return -ENOEXEC ;ENOEXEC means "your executable file doesn't have suitable contents". If this error gets propagated to userspace the poor user will be wondering who corrupted his ELF files and would be surprised to find out that the error in fact came from his packethub driver.
So please use a more appropriate errno here.
Quoted 12 lines
+ }
+ *ppos +=addr_offset;
+ returnaddr_offset;drivers/char/pch_phub/pch_phub.c new file +9
-0+} + +/** pch_phub_write - Implements the write functionality of the Packet Hub +* module. +* @file: Contains the reference of the file structure +* @buf: Usermode buffer pointer +* @size: Usermode buffer size +* @ppos: Contains the reference of the file structure +*/ drivers/char/pch_phub/pch_phub.c line 547
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+static ssize_t pch_phub_write (struct file *file,const char __user *buf, +size_t size,loff_t *ppos) +{ +unsigned int data; +int ret_value; +unsigned int addr_offset =0 ; +loff_t pos = *ppos; + +if (pos <0 ) +return -EINVAL ;
vfs_write()already did that.Quoted 9 lines
+ for (
addr_offset= 0;addr_offset< size; addr_offset++) {
+ret_value=get_user(data, &buf[addr_offset]);
+ if (ret_value)
+ return-EFAULT;
+
+ret_value= pch_phub_write_serial_rom(0x80 +addr_offset+ pos,
+ data);
+ if (ret_value)
+ return-EIO;This overwrites the
pch_phub_write_serial_rom()return value. it's generally better to propagate error return values instead of replacing them with different ones.otoh
pch_phub_write_serial_rom()can return-EPERM. "Operation not permitted. An attempt was made to perform an operation limited to processes with appropriate privileges or to the owner of a file or other resource.". That doesn't sound like an appropriate errno for a driver to use?Quoted 25 lines
+ if (
PCH_PHUB_OROM_SIZE< pos +addr_offset) {
+ *ppos +=addr_offset;
+ returnaddr_offset;
+ }drivers/char/pch_phub/pch_phub.c new file +21
-0+ + } + + *ppos += addr_offset; +return addr_offset; +} + + +/** pch_phub_ioctl - Implements the various ioctl functionalities of the Packet +* Hub module. +* @inode: Contains the reference of the inode structure +* @file: Contains the reference of the file structure +* @cmd: Contains the command value +* @arg: Contains the command argument value +*/ + + +static long pch_phub_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +int ret_value =0 ;drivers/char/pch_phub/pch_phub.c line 593
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+__u8 mac_addr[6 ]; +int ret; +unsigned int i; +void __user *varg = (void __user *)arg; + + ret =mutex_lock_interruptible (&pch_phub_ioctl_mutex); +if (ret) { + ret_value = -ERESTARTSYS ; + goto return_nomutex; + }A plain old `return
-ERESTARTSYS' is OK here.Quoted 2 lines
+ if (pch_phub_reg.pch_phub_suspended == true) {
+ret_value=-EPERM;EPERM?
Quoted 4 lines
+ goto
return_ioctrl;
+ }drivers/char/pch_phub/pch_phub.c new file +2
-0+ +switch (cmd) {drivers/char/pch_phub/pch_phub.c line 610
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+case IOCTL_PHUB_READ_MAC_ADDR : +for (i =0 ; i <6 ; i++) +pch_phub_read_gbe_mac_addr (i, &mac_addr[i]); + + ret_value =copy_to_user (varg, + mac_addr,sizeof (mac_addr)); +if (ret_value) { + ret_value = -EFAULT ; + goto return_ioctrl; + }The goto is unneeded.
drivers/char/pch_phub/pch_phub.c line 619
Quoted 9 lines
+ break;
drivers/char/pch_phub/pch_phub.c new file +8
-0+ +case IOCTL_PHUB_WRITE_MAC_ADDR : + ret_value =copy_from_user (mac_addr, varg,sizeof (mac_addr)); + +if (ret_value) { + ret_value = -EFAULT ; + goto return_ioctrl; + }Could do a `break'.
Quoted 8 lines
+ for (i = 0; i < 6; i++)
+pch_phub_write_gbe_mac_addr(i, mac_addr[i]);
+ break;drivers/char/pch_phub/pch_phub.c new file +5
-0+ +default : + ret_value = -EINVAL ; +break ; + }drivers/char/pch_phub/pch_phub.c line 637
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+return_ioctrl: +mutex_unlock (&pch_phub_ioctl_mutex); +return_nomutex: +return ret_value; +} + + +/** +* file_operations structure initialization +*/ That's not a kerneldoc comment, but it has the /** kerneldoc token.
Quoted 7 lines
drivers/char/pch_phub/pch_phub.c new file +7
-0+static const struct file_operations pch_phub_fops = { + .owner =THIS_MODULE , + .read = pch_phub_read, + .write = pch_phub_write, + .unlocked_ioctl = pch_phub_ioctl, + .llseek = default_llseek +};drivers/char/pch_phub/pch_phub.c line 654
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ + +/** pch_phub_probe - Implements the probe functionality of the module. +* @pdev: Contains the reference of the pci_dev structure +* @id: Contains the reference of the pci_device_id structure +*/ +static int __devinit pch_phub_probe (struct pci_dev *pdev, +const struct pci_device_id *id) +{ +char *DRIVER_NAME ="pch_phub" ;hm, why was that upper case?
Maybe use
MODULE_NAMEinstead? Orstatic const char driver_name[] = "
pch_phub";Quoted 5 lines
+ int ret;
+ unsigned introm_size;
+
+pch_phub_major_no= (pch_phub_major_no< 0 ||pch_phub_major_no> 254) ?
+ 0 :pch_phub_major_no;This looks odd - should be explained in code comments and/or changelog.
Quoted 11 lines
+ ret =
pci_enable_device(pdev);
+ if (ret) {
+ dev_dbg(&pdev->dev,
+ "\npch_phub_probe :pci_enable_deviceFAILED");
+ gotoerr_probe;
+ }
+ dev_dbg(&pdev->dev, "pch_phub_probe: "
+ "pci_enable_devicereturns %d\n", ret);drivers/char/pch_phub/pch_phub.c new file +3
-0+ + ret =pci_request_regions (pdev,DRIVER_NAME ); +if (ret) {drivers/char/pch_phub/pch_phub.c line 681
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+dev_dbg (&pdev->dev, +"pch_phub_probe : pci_request_regions FAILED" ); +pci_disable_device (pdev); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_request_regions returns %d\n" , ret); + + pch_phub_reg.pch_phub_base_address = \ + (void __iomem *)pci_iomap(pdev, 1, 0);Unneeded and undesirable typeast.
drivers/char/pch_phub/pch_phub.c line 695
Quoted 13 lines
+ if (pch_phub_reg.pch_phub_base_address == 0) {
+dev_dbg(&pdev->dev, "pch_phub_probe : pci_iomap FAILED");
+pci_release_regions(pdev);
+pci_disable_device(pdev);
+ ret =-ENOMEM;
+ gotoerr_probe;
+ }
+ dev_dbg(&pdev->dev, "pch_phub_probe:pci_iomapSUCCESS and value "
+ "inpch_phub_base_addressvariable is 0x%08x\n",
+ (unsigned int)pch_phub_reg.pch_phub_base_address);drivers/char/pch_phub/pch_phub.c new file +3
-0+ + pch_phub_reg.pch_phub_extrom_base_address = + (void __iomem *)pci_map_rom (pdev, &rom_size);Ditto
Quoted 5 lines
+ if (pch_phub_reg.pch_phub_extrom_base_address == 0) {
+dev_dbg(&pdev->dev, "pch_phub_probe : pci_map_rom FAILED");
+pci_iounmap(pdev, (void *)pch_phub_reg.pch_phub_base_address);
+pci_release_regions(pdev);
+pci_disable_device(pdev);This is getting painful. I'd suggest removal of the duplicated code via the standard `goto
out_iounmap' unwinding approach.Quoted 9 lines
+ ret =
-ENOMEM;
+ gotoerr_probe;
+ }
+ dev_dbg(&pdev->dev, "pch_phub_probe: "
+ "pci_map_romSUCCESS and value in "
+ "pch_phub_extrom_base_addressvariable is 0x%08x\n",
+ (unsigned int)pch_phub_reg.pch_phub_extrom_base_address);drivers/char/pch_phub/pch_phub.c new file +2
-0+ +if (pch_phub_major_no) {drivers/char/pch_phub/pch_phub.c line 719
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ pch_phub_dev_no =MKDEV (pch_phub_major_no,0 ); + ret =register_chrdev_region (pch_phub_dev_no, +PCH_MINOR_NOS ,DRIVER_NAME ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : " +"register_chrdev_region FAILED" ); +pci_unmap_rom (pdev, + (void *)pch_phub_reg.pch_phub_extrom_base_address); +pci_iounmap (pdev, + (void *)pch_phub_reg.pch_phub_base_address);More unneeded typecasts.
Quoted 8 lines
+
pci_release_regions(pdev);
+pci_disable_device(pdev);
+ gotoerr_probe;
+ }
+ dev_dbg(&pdev->dev, "pch_phub_probe: "
+ "register_chrdev_regionreturns %d\n", ret);
+ } else {
+ ret = alloc_chrdev_region(&pch_phub_dev_no, 0,Quoted 8 lines
+
PCH_MINOR_NOS,DRIVER_NAME);
+ if (ret) {
+ dev_dbg(&pdev->dev, "pch_phub_probe: "
+ "alloc_chrdev_regionFAILED");
+ pci_unmap_rom(pdev,
+ (void *)pch_phub_reg.pch_phub_extrom_base_address);
+ pci_iounmap(pdev,
+ (void *)pch_phub_reg.pch_phub_base_address);more..
Quoted 118 lines
+
pci_release_regions(pdev);
+pci_disable_device(pdev);
+ gotoerr_probe;
+ }
+ dev_dbg(&pdev->dev, "pch_phub_probe: "
+ "alloc_chrdev_regionreturns %d\n", ret);
+ }drivers/char/pch_phub/pch_phub.c new file +108
-0+ +cdev_init (&pch_phub_dev, &pch_phub_fops); +dev_dbg (&pdev->dev, +"pch_phub_probe : cdev_init invoked successfully\n" ); + + pch_phub_dev.owner =THIS_MODULE ; + pch_phub_dev.ops = &pch_phub_fops; + + ret =cdev_add (&pch_phub_dev, pch_phub_dev_no,PCH_MINOR_NOS ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : cdev_add FAILED" ); +unregister_chrdev_region (pch_phub_dev_no,PCH_MINOR_NOS ); +pci_unmap_rom (pdev, + (void *)pch_phub_reg.pch_phub_extrom_base_address); +pci_iounmap (pdev, (void *)pch_phub_reg.pch_phub_base_address); +pci_release_regions (pdev); +pci_disable_device (pdev); + goto err_probe; + } +dev_dbg (&pdev->dev,"pch_phub_probe : cdev_add returns %d\n" , ret); + +/*set the clock config reg if CAN clock is 50Mhz */ +dev_dbg (&pdev->dev,"pch_phub_probe : invoking " +"pch_phub_read_modify_write_reg " +"to set CLKCFG reg for CAN clk 50Mhz\n" ); +pch_phub_read_modify_write_reg ((unsigned int )CLKCFG_REG_OFFSET , +CLKCFG_CAN_50MHZ ,CLKCFG_CANCLK_MASK ); + +/* set the prefech value */ +iowrite32 (0x000ffffa , pch_phub_reg.pch_phub_base_address +0x14 ); +/* set the interrupt delay value */ +iowrite32 (0x25 , pch_phub_reg.pch_phub_base_address +0x44 ); +return 0 ; + +err_probe: +dev_dbg (&pdev->dev,"pch_phub_probe returns %d\n" , ret); +return ret; +} + +#ifdef CONFIG_PM + +/** pch_phub_suspend - Implements the suspend functionality of the module. +* @pdev: Contains the reference of the pci_dev structure +* @state: Contains the reference of the pm_message_t structure +*/ +static int pch_phub_suspend (struct pci_dev *pdev,pm_message_t state) +{ +int ret; + + pch_phub_reg.pch_phub_suspended = true;/* For blocking further IOCTLs */ + +pch_phub_save_reg_conf (pdev); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pch_phub_save_reg_conf Invoked successfully\n" ); + + ret =pci_save_state (pdev); +if (ret) { +dev_dbg (&pdev->dev, +" pch_phub_suspend -pci_save_state returns-%d\n" , ret); +return ret; + } +dev_dbg (&pdev->dev, +"pch_phub_suspend - pci_save_state returns %d\n" , ret); +pci_enable_wake (pdev, PCI_D3hot,0 ); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pci_enable_wake Invoked successfully\n" ); + +pci_disable_device (pdev); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pci_disable_device Invoked successfully\n" ); + +pci_set_power_state (pdev,pci_choose_state (pdev, state)); +dev_dbg (&pdev->dev,"pch_phub_suspend - " +"pci_set_power_state Invoked successfully " +"return = %d\n" ,0 ); + +return 0 ; +} + +/** pch_phub_resume - Implements the resume functionality of the module. +* @pdev: Contains the reference of the pci_dev structure +*/ +static int pch_phub_resume (struct pci_dev *pdev) +{ + +int ret; + +pci_set_power_state (pdev,PCI_D0 ); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_set_power_state Invoked successfully\n" ); + +pci_restore_state (pdev); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_restore_state Invoked successfully\n" ); + + ret =pci_enable_device (pdev); +if (ret) { +dev_dbg (&pdev->dev, +"pch_phub_resume-pci_enable_device failed " ); +return ret; + } + +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_enable_device returns -%d\n" , ret); + +pci_enable_wake (pdev, PCI_D3hot,0 ); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_enable_wake Invoked successfully\n" );drivers/char/pch_phub/pch_phub.c line 891
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +pch_phub_restore_reg_conf (pdev); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pch_phub_restore_reg_conf Invoked successfully\n" ); + + pch_phub_reg.pch_phub_suspended = false; + +dev_dbg (&pdev->dev,"pch_phub_resume returns- %d\n" ,0 ); +return 0 ; +}Here you can put
#else
#definepch_phub_suspendNULL
#definepch_phub_resumeNULLQuoted 8 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+#endif /* CONFIG_PM */ + +static struct pci_device_id pch_phub_pcidev_id[] = { + + {PCI_DEVICE (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_PCH1_PHUB )}, + {0 ,} +}; +drivers/char/pch_phub/pch_phub.c line 909
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +static struct pci_driver pch_phub_driver = { + .name ="pch_phub" , + .id_table = pch_phub_pcidev_id, + .probe = pch_phub_probe, + .remove =__devexit_p (pch_phub_remove), +#ifdef CONFIG_PM + .suspend = pch_phub_suspend, + .resume = pch_phub_resume +#endifand then remove this ifdef.
drivers/char/pch_phub/pch_phub.h line 7
Quoted 13 lines
...
drivers/char/pch_phub/pch_phub.h new file +7
-0@@ -0,0 +1,58 @@ +#ifndef __PCH_PHUB_H__ +#define __PCH_PHUB_H__ +/*! +* @file pch_phub.h +* @brief Provides all the interfaces pertaining to the Packet Hub module. +* @version 1.0.0.0 +* @section ?
Quoted 17 lines
drivers/char/pch_phub/pch_phub.h new file +17
-0+* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* +* History: +* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. drivers/char/pch_phub/pch_phub.h line 34
Quoted 10 lines
drivers/char/pch_phub/pch_phub.h new file +10
-0+* +* created: +* OKI SEMICONDUCTOR 04/14/2010 +* modified: +* +*/ + +#define PHUB_IOCTL_MAGIC (0xf7) + +/*Outlines the read mac address function signature. */ Space after /*, please (check the whole patch)
drivers/char/pch_phub/pch_phub.h line 38
Quoted 4 lines
drivers/char/pch_phub/pch_phub.h new file +4
-0+#define IOCTL_PHUB_READ_MAC_ADDR (_IOR(PHUB_IOCTL_MAGIC, 6, __u8[6])) + +/*brief Outlines the write mac address function signature. */ +#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, __u8[6]))"brief"?
I didn't notice any documentation for these ioctls anywhere?
Quoted 19 lines
drivers/char/pch_phub/pch_phub.h new file +19
-0+ +/* Registers address offset */ +#define PCH_PHUB_PHUB_ID_REG 0x0000 +#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004 +#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008 +#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C +#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010 +#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014 +#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C +#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 +#define CLKCFG_REG_OFFSET 0x500 + +#define PCH_PHUB_OROM_SIZE 15360 + +#endif
Quoted 4 lines · Masayuki Ohtak
Hi, Arnd and Yong Y
I have released Phub patch file.
Please confirm below.
You have addressed all of my comments, the driver looks ready for inclusion from my perspective.
Quoted 1 line
Signed-off-by Masayuki Ohtake <[email protected]>
Quoted 6 lines · Arnd Bergmann
Quoted 4 lines · Masayuki Ohtak
Hi, Arnd and Yong Y
I have released Phub patch file.
Please confirm below.
Quoted 6 lines
You have addressed all of my comments, the driver looks ready for inclusion from my perspective.
Quoted 1 line
Signed-off-by Masayuki Ohtake <[email protected]>Acked-by Arnd Bergmann <[email protected]>
Hi Andrew,
Are you going to take this patch? Or could you please let us know which maintainer will do?
Thanks
-Yong
drivers/char/Kconfig line 13
Quoted 7 lines · Masayuki Ohtak
drivers/char/Kconfig +7
-0+config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + If you say yes to this option, support will be included for the + PCH Packet Hub Host controller. + This driver is for PCH Packet hub driver for Topcliff.
"Topcliff" is probably some kind of internal codename; please use a name that will be visible to customers of this product. References to what kind of device (IEEE standards it implements, what systems it might be present on, etc) are also appropriate.
drivers/char/Kconfig line 14
Quoted 1 line
drivers/char/Kconfig +1
-0+ This driver is integrated as built-in.
This sentence doesn't parse to me. What are you trying to say?
drivers/char/Kconfig line 16
Quoted 2 lines
drivers/char/Kconfig +2
-0+ This driver can access GbE MAC address. + This driver can access HW register.
I think you mean something more like "This driver allows access to the GbE MAC address and HW registers of the PCH Packet Hub."
If this is a driver for an Ethernet MAC, what is it doing in drivers/char/ ?
drivers/char/Kconfig line 17
Quoted 1 line
drivers/char/Kconfig +1
-0+ You can also be integrated as module.
Please look at any other tristate and copy the standard wording.
Quoted 4 lines
+/*!
+ * @filepch_phub.c
+ * @brief Provides all the implementation of the interfaces pertaining to
+ * the Packet Hub module.
We don't normally merge comment markup languages other than kernel-doc. Please read Documentation/kernel-doc-nano-HOWTO.txt and follow it. (Or, provide a pointer to documentation and tools for this mysterious markup language.)
Quoted 7 lines
+/*
+ * History:
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ * OKI SEMICONDUCTOR 04/14/2010
+ * modified:
No changelogs in comments, that's what git history is for.
Quoted 1 line
+/* includes */
Useless comment.
drivers/char/pch_phub/pch_phub.c line 50
Quoted 3 lines
drivers/char/pch_phub/pch_phub.c new file +3
-0+/*-------------------------------------------- +macros +--------------------------------------------*/
More useless comments.
drivers/char/pch_phub/pch_phub.c line 54
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+/* Status Register offset */ +#define PHUB_STATUS 0x00 +/* Control Register offset */ +#define PHUB_CONTROL 0x04
I would format this as:
#define PHUB_STATUS 0x00 /* Status Register offset */ #define PHUB_CONTROL 0x04 /* Control Register offset */
but it's up to you.
drivers/char/pch_phub/pch_phub.c line 97
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+struct pch_phub_reg { +unsigned int phub_id_reg;
Since these are used to hold HW-defined data, you should use fixed-size types such as u32. Also, you should consider whether they should be marked little endian / big endian.
drivers/char/pch_phub/pch_phub.c line 120
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+/* ToDo: major number allocation via module parameter */ +static dev_t pch_phub_dev_no; +static int pch_phub_major_no; +static struct cdev pch_phub_dev;
If this is to remain a chardev, use register_chrdev(). You shouldn't need a module parameter to configure your device numbers.
drivers/char/pch_phub/pch_phub.c line 135
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+ void __iomem *reg_addr = pch_phub_reg.pch_phub_base_address +\ + reg_addr_offset;
That \ is superfluous. There are several of these in this file.
The indentation on the second line is too large, and the fact that "a = b + c" spills onto a second line is a clue that your struct names are too long.
drivers/char/pch_phub/pch_phub.c line 137
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+iowrite32 (((ioread32 (reg_addr) & ~mask)) | data, reg_addr); +return ;
The return is unneeded if this remains a void function. (many more occurrences.)
Quoted 2 lines
+/**
pch_phub_restore_reg_conf- restore register configuration
+ */
Don't use /** unless you're using kernel-doc.
drivers/char/pch_phub/pch_phub.c line 228
Quoted 6 lines
drivers/char/pch_phub/pch_phub.c new file +6
-0+unsigned int i; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_restore_reg_conf ENTRY\n" ); +/* to store contents of PHUB_ID register */ +iowrite32 (pch_phub_reg.phub_id_reg, p +PCH_PHUB_PHUB_ID_REG );
Don't include comments that just duplicate the code. Also, rename your constants from PCH_PHUB_PHUB_ to, I dunno, PHUB_ or something.
Quoted 5 lines
+/**
pch_phub_read_serial_rom- Implements the functionality of reading Serial+ * ROM. + * @offset_address: Contains the Serial ROM address offset value + * @data: Contains the Serial ROM value+ */
This comment is almost correctly formatted, but there are extra words and some whitespace problems, and it doesn't document what actually happens.
+/**
+ * pch_phub_read_serial_rom - read PHUB Serial ROM.
+ * @offset_address: serial ROM offset to read. + * @data: pointer at which to store value that was read.
+ */
is more correct.
Similar problems in several function comments below.
drivers/char/pch_phub/pch_phub.c line 302
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+static int pch_phub_read_serial_rom (unsigned int offset_address, +unsigned char *data)
The second line is indented too far. We use 8-space tabstops, so the "u" of unsigned is all the way over under the "t" of offset_address. It should either be two tabstops indented, or lined up with the previous argument. (This applies to several functions below too.)
It should be "u8 *data".
drivers/char/pch_phub/pch_phub.c line 309
Quoted 6 lines
drivers/char/pch_phub/pch_phub.c new file +6
-0+ void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + offset_address; + + *data =ioread8 (mem_addr); + +return 0 ;
If this can't fail, why not have it just return the value rather than forcing the caller to provide a pointer? (If you want to be futureproof and support errorhandling in the future, that's OK.)
Quoted 11 lines
drivers/char/pch_phub/pch_phub.c new file +11
-0+static int pch_phub_write_serial_rom (unsigned int offset_address, +unsigned char data) +{ +int retval =0 ; + void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + (offset_address &0xFFFFFFFC ); +int i =0 ; +unsigned int word_data =0 ; + + iowrite32(PCH_PHUB_ROM_WRITE_ENABLE, + pch_phub_reg.pch_phub_extrom_base_address +\
drivers/char/pch_phub/pch_phub.c line 337
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ PHUB_CONTROL); + + word_data =ioread32 (mem_addr); + +switch (offset_address %4 ) { +case 0 : + word_data &=0xFFFFFF00 ; +iowrite32 ((word_data | (unsigned int )data), + mem_addr); +break ;
This function is much larger than need be. Remove the 0xFFFFFFFC magic number -- something like
#define PCH_WORD_ADDR_MASK (~((1 << 4) - 1))
and implement the byte masking as something like
pos = (offset_address % 4) * 8;
mask = ~(0xFF << pos);
iowrite32((word_data & mask) | (u32)data << pos, mem_addr);(You can keep the switch if there's a significant performance benefit to doing so, but please provide measurements.)
This is a read-modify-write cycle -- where is the locking if two users try to update the serial ROM simultaneously? Any required locking should be documented in the kernel-doc comment.
drivers/char/pch_phub/pch_phub.c line 362
Quoted 9 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+while (0x00 != +ioread8 (pch_phub_reg.pch_phub_extrom_base_address +\ +PHUB_STATUS )) { +msleep (1 ); +if (PHUB_TIMEOUT == i) { + retval = -EPERM ; +break ; + } + i++;
Rewrite this as a for loop (and remove the initialization from the declaration of i at the top of this function). I am not sure if msleep() is safe here -- what context will this be called from?
drivers/char/pch_phub/pch_phub.c line 384
Quoted 13 lines
drivers/char/pch_phub/pch_phub.c new file +13
-0+/** pch_phub_read_serial_rom_val - Implements the functionality of reading +* Serial ROM value. +* @offset_address: Contains the Serial ROM address offset value +* @data: Contains the Serial ROM value +*/ +static int pch_phub_read_serial_rom_val (unsigned int offset_address, +unsigned char *data) +{ +int retval =0 ; +unsigned int mem_addr; + + mem_addr = (offset_address /4 *8 ) +3 - + (offset_address %4 ) +PCH_PHUB_ROM_START_ADDR ;
Is that formula correct? It is very suprising.
If it is correct, the formula is bizarre enough to warrant a long comment explaining the theory of operation and/or pointing to hardware docs.
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+static ssize_t pch_phub_read (struct file *file,char __user *buf,size_t size, +loff_t *ppos) +{ +unsigned int rom_signature =0 ; +unsigned char rom_length; +int ret_value; +unsigned int tmp; +unsigned char data;
drivers/char/pch_phub/pch_phub.c line 503
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+unsigned int addr_offset =0 ; +unsigned int orom_size; +loff_t pos = *ppos; + +if (pos <0 ) +return -EINVAL ; + +/*Get Rom signature*/ +pch_phub_read_serial_rom (0x80 , (unsigned char *)&rom_signature); +pch_phub_read_serial_rom (0x81 , (unsigned char *)&tmp);
I seriously doubt that your device is special enough to warrant a custom /dev node with proprietary semantics. If this is just part of an Ethernet driver, please implement it in drivers/net/; if this is a generic PROM accessor, there must be some semi-standardized EPROM access interface but I don't know what it is offhand.
-andy
Hi Andy
Thank you for your comments.
Please refer to the following inline.
Thanks, Ohtake.
----- Original Message -----
From: "Andy Isaacson" <[email protected]>
To: "Masayuki Ohtak" <[email protected]>
Cc: "Arnd Bergmann" <[email protected]>; "Wang, Yong Y" <[email protected]>; "Wang Qi" <[email protected]>; "Intel OTC" <[email protected]>; "Andrew" <[email protected]>; "Alan Cox" <[email protected]>; "LKML" <[email protected]>
Sent: Wednesday, June 30, 2010 8:31 AM
Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
Quoted 10 lines · Masayuki Ohtak
drivers/char/Kconfig line 13
Quoted 7 lines
drivers/char/Kconfig +7
-0+config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + If you say yes to this option, support will be included for the + PCH Packet Hub Host controller. + This driver is for PCH Packet hub driver for Topcliff."Topcliff" is probably some kind of internal codename; please use a name
Topcliff is not internal codename but external product name.
Quoted 3 lines
that will be visible to customers of this product. References to what kind of device (IEEE standards it implements, what systems it might be present on, etc) are also appropriate.
I will add what kinds of device.
Quoted 5 lines
Quoted 2 lines
+ This driver is integrated as built-in.
This sentence doesn't parse to me. What are you trying to say?
I will modify above.
Quoted 8 lines
drivers/char/Kconfig line 16
Quoted 2 lines
drivers/char/Kconfig +2
-0+ This driver can access GbE MAC address. + This driver can access HW register.I think you mean something more like "This driver allows access to the GbE MAC address and HW registers of the PCH Packet Hub."
If this is a driver for an Ethernet MAC, what is it doing in
drivers/char/?
In Topcliff, MAC address is in PHUB HW not in GbE HW.
Quoted 4 lines
Quoted 2 lines
+ You can also be integrated as module.
Please look at any other tristate and copy the standard wording.
I will modify above.
Quoted 10 lines
Quoted 5 lines
+/*!
+ * @filepch_phub.c
+ * @brief Provides all the implementation of the interfaces pertaining to
+ * the Packet Hub module.We don't normally merge comment markup languages other than kernel-doc. Please read
Documentation/kernel-doc-nano-HOWTO.txtand follow it. (Or, provide a pointer to documentation and tools for this mysterious markup language.)
I will modify above.
Quoted 10 lines
Quoted 8 lines
+/*
+ * History:
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ * OKI SEMICONDUCTOR 04/14/2010
+ * modified:No changelogs in comments, that's what git history is for.
I will modify above.
Quoted 4 lines
Quoted 2 lines
+/* includes */
Useless comment.
I will delete above.
Quoted 6 lines
Quoted 4 lines
+/*--------------------------------------------
+ macros
+--------------------------------------------*/More useless comments.
I will delete above.
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c line 54
Quoted 5 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+/* Status Register offset */ +#define PHUB_STATUS 0x00 +/* Control Register offset */ +#define PHUB_CONTROL 0x04I would format this as:
Quoted 4 lines
#define PHUB_STATUS 0x00 /* Status Register offset */ #define PHUB_CONTROL 0x04 /* Control Register offset */but it's up to you.
I will modify above.
Quoted 7 lines
Quoted 3 lines
+struct
pch_phub_reg{
+ unsigned intphub_id_reg;Since these are used to hold HW-defined data, you should use fixed-size types such as u32. Also, you should consider whether they should be marked little endian / big endian.
I will modify above.
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c line 120
Quoted 5 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+/* ToDo: major number allocation via module parameter */ +static dev_t pch_phub_dev_no; +static int pch_phub_major_no; +static struct cdev pch_phub_dev;If this is to remain a chardev, use
register_chrdev(). You shouldn't need a module parameter to configure your device numbers.
I will delete module paramter.
Quoted 5 lines
Quoted 3 lines
+ void
__iomem*reg_addr= pch_phub_reg.pch_phub_base_address +\
+reg_addr_offset;That \ is superfluous. There are several of these in this file.
I will delete uncecessary '\'.
Quoted 4 lines
The indentation on the second line is too large, and the fact that "a = b + c" spills onto a second line is a clue that your struct names are too long.
We don't modify structure name this time.
Quoted 6 lines
Quoted 3 lines
+
iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
+ return;The return is unneeded if this remains a void function. (many more occurrences.)
I will delete 'return' of void function.
Quoted 5 lines
Quoted 3 lines
+/**
pch_phub_restore_reg_conf- restore register configuration
+ */Don't use /** unless you're using kernel-doc.
I will modify above.
Quoted 10 lines
Quoted 7 lines
+ unsigned int i;
+ void__iomem*p = pch_phub_reg.pch_phub_base_address; +
+dev_dbg(&pdev->dev, "pch_phub_restore_reg_conf ENTRY\n");
+ /* to store contents ofPHUB_IDregister */
+iowrite32(pch_phub_reg.phub_id_reg, p + PCH_PHUB_PHUB_ID_REG);Don't include comments that just duplicate the code. Also, rename your constants from
PCH_PHUB_PHUB_to, I dunno,PHUB_or something.
Sorry, I can't understand your intention.
Please give us more information.
Quoted 10 lines
Quoted 6 lines
+/**
pch_phub_read_serial_rom- Implements the functionality of reading Serial+ * ROM. + * @offset_address: Contains the Serial ROM address offset value + * @data: Contains the Serial ROM value+ */
This comment is almost correctly formatted, but there are extra words and some whitespace problems, and it doesn't document what actually happens.
I will modify above.
Quoted 8 lines
+/**
+ *pch_phub_read_serial_rom- read PHUB Serial ROM.+ * @offset_address: serial ROM offset to read. + * @data: pointer at which to store value that was read.+ */
is more correct.
I will modify above.
Quoted 10 lines
Similar problems in several function comments below.
Quoted 2 lines
+static int pch_phub_read_serial_rom(unsigned int
offset_address,
+ unsigned char *data)The second line is indented too far. We use 8-space tabstops, so the "u" of unsigned is all the way over under the "t" of
offset_address. It should either be two tabstops indented, or lined up with the previous argument. (This applies to several functions below too.)
I will modify above.
Quoted 2 lines
It should be "u8 *data".
I will modify above.
Quoted 11 lines
drivers/char/pch_phub/pch_phub.c line 309
Quoted 7 lines
+ void
__iomem*mem_addr= pch_phub_reg.pch_phub_extrom_base_address +\
+offset_address;drivers/char/pch_phub/pch_phub.c new file +4
-0+ + *data =ioread8 (mem_addr); + +return 0 ;If this can't fail, why not have it just return the value rather than forcing the caller to provide a pointer? (If you want to be futureproof and support errorhandling in the future, that's OK.)
I will modify to void.
Quoted 28 lines
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +11
-0+static int pch_phub_write_serial_rom (unsigned int offset_address, +unsigned char data) +{ +int retval =0 ; + void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\ + (offset_address &0xFFFFFFFC ); +int i =0 ; +unsigned int word_data =0 ; + + iowrite32(PCH_PHUB_ROM_WRITE_ENABLE, + pch_phub_reg.pch_phub_extrom_base_address +\drivers/char/pch_phub/pch_phub.c line 337
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ PHUB_CONTROL); + + word_data =ioread32 (mem_addr); + +switch (offset_address %4 ) { +case 0 : + word_data &=0xFFFFFF00 ; +iowrite32 ((word_data | (unsigned int )data), + mem_addr); +break ;This function is much larger than need be. Remove the
0xFFFFFFFCmagic number -- something like#define
PCH_WORD_ADDR_MASK(~((1 << 4) - 1))
Quoted 8 lines
and implement the byte masking as something like
pos = (offset_address % 4) * 8; mask = ~(0xFF << pos); iowrite32((word_data & mask) | (u32)data << pos, mem_addr);(You can keep the switch if there's a significant performance benefit to doing so, but please provide measurements.)
I will modify.(This processing is not performance critical.)
Quoted 4 lines
This is a read-modify-write cycle -- where is the locking if two users try to update the serial ROM simultaneously? Any required locking should be documented in the kernel-doc comment.
I will modify using MUTEX like ioctl.
Quoted 11 lines
Quoted 10 lines
+ while (
0x00!=
+ ioread8(pch_phub_reg.pch_phub_extrom_base_address +\
+PHUB_STATUS)) {
+ msleep(1);
+ if (PHUB_TIMEOUT== i) {
+ retval =-EPERM;
+ break;
+ }
+ i++;
Quoted 3 lines
Rewrite this as a for loop (and remove the initialization from the declaration of i at the top of this function). I am not sure if
msleep()is safe here -- what context will this be called from?
This function is called from ioctl context(not interrput). Thus, I think safe.
Quoted 17 lines
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +3
-0+/** pch_phub_read_serial_rom_val - Implements the functionality of reading +* Serial ROM value. +* @offset_address: Contains the Serial ROM address offset value drivers/char/pch_phub/pch_phub.c line 384
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+* @data: Contains the Serial ROM value +*/ +static int pch_phub_read_serial_rom_val (unsigned int offset_address, +unsigned char *data) +{ +int retval =0 ; +unsigned int mem_addr; + + mem_addr = (offset_address /4 *8 ) +3 - + (offset_address %4 ) +PCH_PHUB_ROM_START_ADDR ;Is that formula correct? It is very suprising.
Quoted 3 lines
If it is correct, the formula is bizarre enough to warrant a long comment explaining the theory of operation and/or pointing to hardware docs.
I will modify the above and add comments.
Quoted 17 lines
Quoted 17 lines
drivers/char/pch_phub/pch_phub.c new file +16
-0+static ssize_t pch_phub_read (struct file *file,char __user *buf,size_t size, +loff_t *ppos) +{ +unsigned int rom_signature =0 ; +unsigned char rom_length; +int ret_value; +unsigned int tmp; +unsigned char data; +unsigned int addr_offset =0 ; +unsigned int orom_size; +loff_t pos = *ppos; + +if (pos <0 ) +return -EINVAL ; + +/*Get Rom signature*/
Quoted 8 lines
Quoted 2 lines
+
pch_phub_read_serial_rom(0x80, (unsigned char *)&rom_signature);
+pch_phub_read_serial_rom(0x81, (unsigned char *)&tmp);I seriously doubt that your device is special enough to warrant a custom /dev node with proprietary semantics. If this is just part of an Ethernet driver, please implement it in
drivers/net/; if this is a generic PROM accessor, there must be some semi-standardized EPROM access interface but I don't know what it is offhand.
Since SROM is not in GbE HW but Phub HW, Phub is not part of Ethernet driver. Packet hub is not generic driver but special device.
Quoted 3 lines
-andy
Quoted 7 lines · Masayuki Ohtake
Quoted 7 lines
Quoted 6 lines
+ unsigned int i;
+ void__iomem*p = pch_phub_reg.pch_phub_base_address; +
+dev_dbg(&pdev->dev, "pch_phub_restore_reg_conf ENTRY\n");
+ /* to store contents ofPHUB_IDregister */
+iowrite32(pch_phub_reg.phub_id_reg, p + PCH_PHUB_PHUB_ID_REG);
Quoted 5 lines
Quoted 2 lines
Don't include comments that just duplicate the code. Also, rename your constants from
PCH_PHUB_PHUB_to, I dunno,PHUB_or something.Sorry, I can't understand your intention.
Please give us more information.
My mistake, I merged two comments into one paragraph, let me clarify.
1. When writing comments, do not write comments that duplicate the code. Instead of writing
/* store PHUB_ID */ iowrite32(..._PHUB_ID_REG); /* store PHUB_FOO */ iowrite32(..._PHUB_FOO_REG); you should delete the line-by-line comments and just write iowrite32(..._PHUB_ID_REG); iowrite32(..._PHUB_FOO_REG);
2. your register names are very long. Since the #define names are private to this driver, there's no need to make them extremely descriptive. Instead of naming your registers PCH_PHUB_PHUB_ID_REG, you should change the names to be shorter, like PHUB_ID_REG or PCH_ID_REG. This will make your source code much more readable by reducing linewrapping.
Quoted 8 lines
Quoted 5 lines
I seriously doubt that your device is special enough to warrant a custom /dev node with proprietary semantics. If this is just part of an Ethernet driver, please implement it in
drivers/net/; if this is a generic PROM accessor, there must be some semi-standardized EPROM access interface but I don't know what it is offhand.Since SROM is not in GbE HW but Phub HW, Phub is not part of Ethernet driver. Packet hub is not generic driver but special device.
It sounds like PHUB is a system-level device which provides access to a SROM which contains GbE configuration data. If that is correct, then I have two comments:
1. There are many other systems with similar configurations -- MIPS SiByte, Alpha SRM, SPARC OpenFirmware, and some ARM systems, just to name a few. None of them expose the SROM as a custom /dev node AFAIK. Is there a shared infrastructure that you can implement?
2. How does your GbE driver get the MAC address from the SPROM? If there is an in-kernel user of the PHUB interface, it might be much easier to understand the design.
Thanks for responding to my review so quickly!
-andy
Hi Andy,
Quoted 2 lines
1. When writing comments, do not write comments that duplicate the code. Instead of writing
Our Phub patch I have resubmitted yesterday have been already modified above.
Quoted 6 lines
2. your register names are very long. Since the #define names are private to this driver, there's no need to make them extremely descriptive. Instead of naming your registers
PCH_PHUB_PHUB_ID_REG, you should change the names to be shorter, likePHUB_ID_REGorPCH_ID_REG. This will make your source code much more readable by reducing linewrapping.
This was our mistake.
I have modified PCH_PHUB_PHUB_ID_REG to PCH_PHUB_ID_REG.
Our Phub patch I have resubmitted yesterday have been already modified above.
Quoted 3 lines
It sounds like PHUB is a system-level device which provides access to a SROM which contains GbE configuration data. If that is correct, then I have two comments:
Yes, SROM has GbE configuration data (GbE mac address) .
Quoted 5 lines
1. There are many other systems with similar configurations -- MIPS SiByte, Alpha SRM, SPARC OpenFirmware, and some ARM systems, just to name a few. None of them expose the SROM as a custom /dev node AFAIK. Is there a shared infrastructure that you can implement?
Sorry, I can't understand your intension.
Please give me more detail.
Quoted 4 lines
2. How does your GbE driver get the MAC address from the SPROM? If there is an in-kernel user of the PHUB interface, it might be much easier to understand the design.
PHUB HW transfers MAC address(in SROM) data to GbE register to set MAC address when boot processing.
Thanks, Ohtake
----- Original Message -----
From: "Andy Isaacson" <[email protected]>
To: "Masayuki Ohtake" <[email protected]>
Cc: "Arnd Bergmann" <[email protected]>; "Wang, Yong Y" <[email protected]>; "Wang Qi" <[email protected]>; "Intel OTC" <[email protected]>; "Andrew" <[email protected]>; "Alan Cox" <[email protected]>; "LKML" <[email protected]>
Sent: Thursday, July 01, 2010 3:28 AM
Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
Quoted 58 lines · Masayuki Ohtake
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
+ unsigned int i;
+ void__iomem*p = pch_phub_reg.pch_phub_base_address; +
+dev_dbg(&pdev->dev, "pch_phub_restore_reg_conf ENTRY\n");
+ /* to store contents ofPHUB_IDregister */
+iowrite32(pch_phub_reg.phub_id_reg, p + PCH_PHUB_PHUB_ID_REG);Quoted 5 lines
Quoted 2 lines
Don't include comments that just duplicate the code. Also, rename your constants from
PCH_PHUB_PHUB_to, I dunno,PHUB_or something.Sorry, I can't understand your intention.
Please give us more information.My mistake, I merged two comments into one paragraph, let me clarify.
1. When writing comments, do not write comments that duplicate the code. Instead of writing
/* storePHUB_ID*/iowrite32(..._PHUB_ID_REG);
/* storePHUB_FOO*/iowrite32(..._PHUB_FOO_REG);
you should delete the line-by-line comments and just writeiowrite32(..._PHUB_ID_REG);iowrite32(..._PHUB_FOO_REG);2. your register names are very long. Since the #define names are private to this driver, there's no need to make them extremely descriptive. Instead of naming your registers
PCH_PHUB_PHUB_ID_REG, you should change the names to be shorter, likePHUB_ID_REGorPCH_ID_REG. This will make your source code much more readable by reducing linewrapping.Quoted 8 lines
Quoted 5 lines
I seriously doubt that your device is special enough to warrant a custom /dev node with proprietary semantics. If this is just part of an Ethernet driver, please implement it in
drivers/net/; if this is a generic PROM accessor, there must be some semi-standardized EPROM access interface but I don't know what it is offhand.Since SROM is not in GbE HW but Phub HW, Phub is not part of Ethernet driver. Packet hub is not generic driver but special device.
It sounds like PHUB is a system-level device which provides access to a SROM which contains GbE configuration data. If that is correct, then I have two comments:
1. There are many other systems with similar configurations -- MIPS SiByte, Alpha SRM, SPARC OpenFirmware, and some ARM systems, just to name a few. None of them expose the SROM as a custom /dev node AFAIK. Is there a shared infrastructure that you can implement?
2. How does your GbE driver get the MAC address from the SPROM? If there is an in-kernel user of the PHUB interface, it might be much easier to understand the design.
Thanks for responding to my review so quickly!
-andy
PATCH 1/1 Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakHi Andy and Andrew
I have modified for your comments.
Please confirm below.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel’s upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH have MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
--- drivers/char/Kconfig | 10 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 805 ++++++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 +++ 5 files changed, 868 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
drivers/char/Kconfig +10 -0
@@ -4,6 +4,16 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + Topcliff is a IOH for x86 embedded processor. This IOH is quite + different with the traditional IOH. Topcliff is a kind of ARM-based + processor and connected with PCIe bus (from x86 processor). + PHUB work as a gateway transform the PCIe transaction into the AMBA + transaction, and vise verse, and have several transform windows also. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +805 -0
805 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +48 -0
48 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 21 lines · On Wed, 30 Jun 2010 16:51:30 +0900 Masayuki Ohtak wrote:
Hi Andy and Andrew
I have modified for your comments.
Please confirm below.---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel’s upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH have MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
Quoted 2 lines
Signed-off-by Masayuki Ohtake <[email protected]>Acked-by Arnd <Arnd’s email address>
It's listed in the MAINTAINERS file. Please use that.
Quoted 6 lines
drivers/char/Kconfig +0
-0
drivers/char/Kconfig line 11
Quoted 8 lines
drivers/char/Kconfig +5
-0@@ -4,6 +4,16 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + Topcliff is a IOH for x86 embedded processor. This IOH is quite
is an IOH for x86 embedded processors.
drivers/char/Kconfig line 12
Quoted 1 line
drivers/char/Kconfig +1
-0+ different with the traditional IOH. Topcliff is a kind of ARM-based
from
drivers/char/Kconfig line 14
Quoted 2 lines
drivers/char/Kconfig +2
-0+ processor and connected with PCIe bus (from x86 processor). + PHUB work as a gateway transform the PCIe transaction into the AMBA
works as a gateway to transform
drivers/char/Kconfig line 15
Quoted 1 line
drivers/char/Kconfig +1
-0+ transaction, and vise verse, and have several transform windows also.
vice versa, and has several
Maybe lose some acromyns? Overall, this help text should be about *what* PCH_PHUB is, not *how* it accomplishes its work.
If you want to document *how* it works, put that into the source code or Documentation/ somewhere.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Re: [PATCH] Packet hub driver of Topcliff PCH
Hi Randy
Quoted 1 line
It's listed in the
MAINTAINERSfile. Please use that.
I will add Arnd's e-mail address.
Quoted 4 lines
Maybe lose some acromyns? Overall, this help text should be about *what*
PCH_PHUBis, not *how* it accomplishes its work.
If you want to document *how* it works, put that into the source code orDocumentation/somewhere.
I will rewrite my help text.
Thanks, Ohtake
----- Original Message -----
From: "Randy Dunlap" <[email protected]>
To: "Masayuki Ohtak" <[email protected]>
Cc: "Andy Isaacson" <[email protected]>; "Andrew Morton" <[email protected]>; "Arnd Bergmann" <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>; <[email protected]>; "Alan Cox" <[email protected]>; "LKML" <[email protected]>
Sent: Thursday, July 01, 2010 3:05 AM
Subject: Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 71 lines · On Wed, 30 Jun 2010 16:51:30 +0900 Masayuki Ohtak wrote:
Quoted 22 lines
Hi Andy and Andrew
I have modified for your comments.
Please confirm below.---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel$B!G(Bs upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH have MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.Quoted 2 lines
Signed-off-by Masayuki Ohtake <[email protected]>Acked-by Arnd <Arnd$B!G(Bs email address>It's listed in the
MAINTAINERSfile. Please use that.Quoted 6 lines
drivers/char/Kconfig +0
-0drivers/char/Kconfig line 11
Quoted 8 lines
drivers/char/Kconfig +5
-0@@ -4,6 +4,16 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + Topcliff is a IOH for x86 embedded processor. This IOH is quiteis an IOH for x86 embedded processors.
drivers/char/Kconfig line 12
Quoted 1 line
drivers/char/Kconfig +1
-0+ different with the traditional IOH. Topcliff is a kind of ARM-basedfrom
drivers/char/Kconfig line 14
Quoted 2 lines
drivers/char/Kconfig +2
-0+ processor and connected with PCIe bus (from x86 processor). + PHUB work as a gateway transform the PCIe transaction into the AMBAworks as a gateway to transform
drivers/char/Kconfig line 15
Quoted 1 line
drivers/char/Kconfig +1
-0+ transaction, and vise verse, and have several transform windows also.vice versa, and has several
Maybe lose some acromyns? Overall, this help text should be about *what*
PCH_PHUBis, not *how* it accomplishes its work.
If you want to document *how* it works, put that into the source code orDocumentation/somewhere.---
~Randy
*** Remember to useDocumentation/SubmitChecklistwhen testing your code ***
PATCH 1/1 Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakHi Andy and Randy
I have modified for your comments.
Please confirm below.
Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH have MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
--- drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 805 ++++++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 +++ 5 files changed, 867 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
drivers/char/Kconfig +9 -0
@@ -4,6 +4,15 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + This driver is for PCH PHUB of Topcliff which is an IOH for x86 + embedded processor. The Topcliff has MAC address and Option ROM data + in SROM. This dirver can access MAC address and Option ROM data in + SROM. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +805 -0
805 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +48 -0
48 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 4 lines · Masayuki Ohtak
Hi Andy and Randy
I have modified for your comments.
Please confirm below.
Your style is looking better, and the additional documentation is much appreciated.
I still have concerns about the userland interface design. It still seems to me that the MAC interface should be used by something in drivers/net and there's no reason to expose the SROM in /dev unless it contains more than just the MAC address.
A few more style issues I saw on a quick scan through -- this was not a comprehensive review:
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+static long pch_phub_ioctl (struct file *file,unsigned int cmd, +unsigned long arg)
[snip]
drivers/char/pch_phub/pch_phub.c line 524
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+ ret_value =copy_to_user (varg, + mac_addr,sizeof (mac_addr));
Reformat this to fit on one line:
+ ret_value = copy_to_user(varg, mac_addr, sizeof(mac_addr));
[snip]
drivers/char/pch_phub/pch_phub.c line 533
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+case IOCTL_PHUB_WRITE_MAC_ADDR : + ret_value =copy_from_user (mac_addr, varg,sizeof (mac_addr)); + +if (ret_value)
Here we need to break:
+ {
Review
Quoted 1 line
(quoted diff) +1
-0+ ret_value = -EFAULT;
+ break;
+ }
because if copy_from_user failed ...
Review
Quoted 2 lines
(quoted diff) +2
-0+ for (i = 0; i < 6; i++) + pch_phub_write_gbe_mac_addr(i, mac_addr[i]);
... we would pass garbage to pch_phub_write_gbe_mac_addr.
[snip]
drivers/char/pch_phub/pch_phub.c line 570
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+dev_dbg (&pdev->dev, +"\npch_phub_probe : pci_enable_device FAILED" );
Prefix \n is not correct. This should be
+ dev_dbg(&pdev->dev, "pch_phub_probe: pci_enable_device FAILED");
In general dev_dbg format strings should fit on one 80-char line. If your format strings are longer than that, it's a clue you're doing something wrong. For example:
drivers/char/pch_phub/pch_phub.c line 574
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_enable_device returns %d\n" , ret);
+ dev_dbg(&pdev->dev, "pch_phub_probe: pci_enable_device returns %d\n",
+ ret);
drivers/char/pch_phub/pch_phub.c line 579
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+ ret =pci_request_regions (pdev,MODULE_NAME ); +if (ret) { +dev_dbg (&pdev->dev, +"pch_phub_probe : pci_request_regions FAILED" );
If you have a dev_dbg, please print ret. It may give an important clue.
[snip a bunch more I don't have time to review right now]
Thanks,
-andy
Re: [PATCH] Packet hub driver of Topcliff PCH
Hi Andy,
Quoted 4 lines
I still have concerns about the userland interface design. It still seems to me that the MAC interface should be used by something in
drivers/netand there's no reason to expose the SROM in /dev unless it contains more than just the MAC address.
SROM has not only MAC address but also Option ROM data. Thus, we think SROM should be exposed.
Quoted 2 lines
A few more style issues I saw on a quick scan through -- this was not a comprehensive review:
We are now modifying.
Thanks, Ohtake
----- Original Message -----
From: "Andy Isaacson" <[email protected]>
To: "Masayuki Ohtak" <[email protected]>
Cc: "Randy Dunlap" <[email protected]>; "Arnd Bergmann" <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>; <[email protected]>; "Alan Cox" <[email protected]>; "LKML" <[email protected]>
Sent: Thursday, July 01, 2010 3:58 PM
Subject: Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 79 lines · Masayuki Ohtak
Quoted 4 lines
Hi Andy and Randy
I have modified for your comments.
Please confirm below.Your style is looking better, and the additional documentation is much appreciated.
I still have concerns about the userland interface design. It still seems to me that the MAC interface should be used by something in
drivers/netand there's no reason to expose the SROM in /dev unless it contains more than just the MAC address.A few more style issues I saw on a quick scan through -- this was not a comprehensive review:
Quoted 2 lines
drivers/char/pch_phub/pch_phub.c new file +2
-0+static long pch_phub_ioctl (struct file *file,unsigned int cmd, +unsigned long arg)[snip]
Quoted 2 lines
+
ret_value= copy_to_user(varg,
+mac_addr,sizeof(mac_addr));Reformat this to fit on one line:
+ret_value=copy_to_user(varg, mac_addr, sizeof(mac_addr));[snip]
Quoted 4 lines
+ case
IOCTL_PHUB_WRITE_MAC_ADDR:
+ret_value=copy_from_user(mac_addr, varg, sizeof(mac_addr)); +
+ if (ret_value)Here we need to break:
+ {
Quoted 1 line
+
ret_value=-EFAULT;(quoted diff) +2
-0+ break; + }because if
copy_from_userfailed ...Quoted 2 lines
+ for (i = 0; i < 6; i++)
+pch_phub_write_gbe_mac_addr(i, mac_addr[i]);... we would pass garbage to
pch_phub_write_gbe_mac_addr.[snip]
Quoted 2 lines
+ dev_dbg(&pdev->dev,
+ "\npch_phub_probe :pci_enable_deviceFAILED");Prefix \n is not correct. This should be
+
dev_dbg(&pdev->dev, "pch_phub_probe: pci_enable_device FAILED");In general
dev_dbgformat strings should fit on one 80-char line. If your format strings are longer than that, it's a clue you're doing something wrong. For example:Quoted 2 lines
+ dev_dbg(&pdev->dev, "
pch_phub_probe: "
+ "pci_enable_devicereturns %d\n", ret);+ dev_dbg(&pdev->dev, "
pch_phub_probe:pci_enable_devicereturns %d\n",
+ ret);Quoted 4 lines
+ ret =
pci_request_regions(pdev, MODULE_NAME);
+ if (ret) {
+ dev_dbg(&pdev->dev,
+ "pch_phub_probe:pci_request_regionsFAILED");If you have a
dev_dbg, please print ret. It may give an important clue.[snip a bunch more I don't have time to review right now]
Thanks,
-andy
PATCH 1/1 Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakHi Andy
I have modified for your comments.
Please confirm below.
Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH have MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
--- drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 811 ++++++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 +++ 5 files changed, 873 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
drivers/char/Kconfig +9 -0
@@ -4,6 +4,15 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + This driver is for PCH PHUB of Topcliff which is an IOH for x86 + embedded processor. The Topcliff has MAC address and Option ROM data + in SROM. This dirver can access MAC address and Option ROM data in + SROM. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +811 -0
811 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +48 -0
48 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 32 lines · Masayuki Ohtak
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH have MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.Signed-off-by Masayuki Ohtake <[email protected]>Acked-by Arnd Bergmann <[email protected]>--- drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 811 ++++++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 +++ 5 files changed, 873 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.hdrivers/char/Kconfig +0
-0
drivers/char/Kconfig line 13
Quoted 10 lines
drivers/char/Kconfig +7
-0@@ -4,6 +4,15 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + This driver is for PCH PHUB of Topcliff which is an IOH for x86 + embedded processor. The Topcliff has MAC address and Option ROM data + in SROM. This dirver can access MAC address and Option ROM data in
driver
drivers/char/pch_phub/pch_phub.c line 1
Quoted 13 lines
drivers/char/Kconfig +2
-0+ SROM. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390drivers/char/pch_phub/pch_phub.c new file +1
-0@@ -0,0 +1,811 @@ +/*!
What is the ! for?
Quoted 156 lines
drivers/char/pch_phub/pch_phub.c new file +156
-0+* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/uaccess.h> +#include <linux/string.h> +#include <linux/pci.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/cdev.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include "pch_phub.h" + +#define PHUB_STATUS 0x00/* Status Register offset */ +#define PHUB_CONTROL 0x04/* Control Register offset */ +#define PHUB_TIMEOUT 0x05/* Time out value for Status Register */ +#define PCH_PHUB_ROM_WRITE_ENABLE 0x01/* Enabling for writing ROM */ +#define PCH_PHUB_ROM_WRITE_DISABLE 0x00/* Disabling for writing ROM */ +#define PCH_PHUB_ROM_START_ADDR 0x14/* ROM data area start address offset */ + +/* MAX number of INT_REDUCE_CONTROL registers */ +#define MAX_NUM_INT_REDUCE_CONTROL_REG 128 +#define PCI_DEVICE_ID_PCH1_PHUB 0x8801 +#define PCH_MINOR_NOS 1 +#define CLKCFG_CAN_50MHZ 0x12000000 +#define CLKCFG_CANCLK_MASK 0xFF000000 +#define MODULE_NAME "pch_phub" + +/** +* struct pch_phub_reg - PHUB register structure +* @phub_id_reg: PHUB_ID register val +* @q_pri_val_reg: QUEUE_PRI_VAL register val +* @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val +* @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val +* @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val +* @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val +* @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val +* @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val +* @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val +* @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val +* @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val +* @int_reduce_control_reg: INT_REDUCE_CONTROL registers val +* @clkcfg_reg: CLK CFG register val +* @pch_phub_base_address: Register base address +* @pch_phub_extrom_base_address: external rom base address +* @pch_phub_suspended: PHUB status val +*/ +struct pch_phub_reg { +u32 phub_id_reg; +u32 q_pri_val_reg; +u32 rc_q_maxsize_reg; +u32 bri_q_maxsize_reg; +u32 comp_resp_timeout_reg; +u32 bus_slave_control_reg; +u32 deadlock_avoid_type_reg; +u32 intpin_reg_wpermit_reg0; +u32 intpin_reg_wpermit_reg1; +u32 intpin_reg_wpermit_reg2; +u32 intpin_reg_wpermit_reg3; +u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG ]; +u32 clkcfg_reg; +void __iomem *pch_phub_base_address; +void __iomem *pch_phub_extrom_base_address; +int pch_phub_suspended; +} pch_phub_reg; + +/* SROM SPEC for MAC address assignment offset */ +static const int pch_phub_mac_offset[6 ] = {0x3 ,0x2 ,0x1 ,0x0 ,0xb ,0xa }; + +static DEFINE_MUTEX (pch_phub_ioctl_mutex); +static DEFINE_MUTEX (pch_phub_read_mutex); +static DEFINE_MUTEX (pch_phub_write_mutex); +static dev_t pch_phub_dev_no; +static struct cdev pch_phub_dev; + +/** +* pch_phub_read_modify_write_reg() - Reading modifying and writing register +* @reg_addr_offset: Register offset address value. +* @data: Writing value. +* @mask: Mask value. +*/ +static void pch_phub_read_modify_write_reg (unsigned int reg_addr_offset, +unsigned int data,unsigned int mask) +{ +void __iomem *reg_addr = pch_phub_reg.pch_phub_base_address + + reg_addr_offset; +iowrite32 (((ioread32 (reg_addr) & ~mask)) | data, reg_addr); +} + + +/* pch_phub_save_reg_conf - saves register configuration */ +static void pch_phub_save_reg_conf (struct pci_dev *pdev) +{ +unsigned int i; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf ENTRY\n" ); + pch_phub_reg.phub_id_reg =ioread32 (p +PCH_PHUB_ID_REG ); + pch_phub_reg.q_pri_val_reg =ioread32 (p +PCH_PHUB_QUEUE_PRI_VAL_REG ); + pch_phub_reg.rc_q_maxsize_reg = +ioread32 (p +PCH_PHUB_RC_QUEUE_MAXSIZE_REG ); + pch_phub_reg.bri_q_maxsize_reg = +ioread32 (p +PCH_PHUB_BRI_QUEUE_MAXSIZE_REG ); + pch_phub_reg.comp_resp_timeout_reg = +ioread32 (p +PCH_PHUB_COMP_RESP_TIMEOUT_REG ); + pch_phub_reg.bus_slave_control_reg = +ioread32 (p +PCH_PHUB_BUS_SLAVE_CONTROL_REG ); + pch_phub_reg.deadlock_avoid_type_reg = +ioread32 (p +PCH_PHUB_DEADLOCK_AVOID_TYPE_REG ); + pch_phub_reg.intpin_reg_wpermit_reg0 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG0 ); + pch_phub_reg.intpin_reg_wpermit_reg1 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG1 ); + pch_phub_reg.intpin_reg_wpermit_reg2 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG2 ); + pch_phub_reg.intpin_reg_wpermit_reg3 = +ioread32 (p +PCH_PHUB_INTPIN_REG_WPERMIT_REG3 ); + dev_dbg(&pdev->dev, "pch_phub_save_reg_conf : " + "pch_phub_reg.phub_id_reg=%x, " + "pch_phub_reg.q_pri_val_reg=%x, " + "pch_phub_reg.rc_q_maxsize_reg=%x, " + "pch_phub_reg.bri_q_maxsize_reg=%x, " + "pch_phub_reg.comp_resp_timeout_reg=%x, " + "pch_phub_reg.bus_slave_control_reg=%x, " + "pch_phub_reg.deadlock_avoid_type_reg=%x, " + "pch_phub_reg.intpin_reg_wpermit_reg0=%x, " + "pch_phub_reg.intpin_reg_wpermit_reg1=%x, " + "pch_phub_reg.intpin_reg_wpermit_reg2=%x, " + "pch_phub_reg.intpin_reg_wpermit_reg3=%x\n", + pch_phub_reg.phub_id_reg, + pch_phub_reg.q_pri_val_reg, + pch_phub_reg.rc_q_maxsize_reg, + pch_phub_reg.bri_q_maxsize_reg, + pch_phub_reg.comp_resp_timeout_reg, + pch_phub_reg.bus_slave_control_reg, + pch_phub_reg.deadlock_avoid_type_reg, + pch_phub_reg.intpin_reg_wpermit_reg0, + pch_phub_reg.intpin_reg_wpermit_reg1, + pch_phub_reg.intpin_reg_wpermit_reg2,
drivers/char/pch_phub/pch_phub.c line 167
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ pch_phub_reg.intpin_reg_wpermit_reg3); +for (i =0 ; i <MAX_NUM_INT_REDUCE_CONTROL_REG ; i++) { + pch_phub_reg.int_reduce_control_reg[i] = +ioread32 (p +PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE +4 * i); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.int_reduce_control_reg[%d]=%x\n" , + i, pch_phub_reg.int_reduce_control_reg[i]); + } + pch_phub_reg.clkcfg_reg =ioread32 (p +CLKCFG_REG_OFFSET ); +
drop blank line above.
Quoted 92 lines
drivers/char/pch_phub/pch_phub.c new file +92
-0+} + +/* pch_phub_restore_reg_conf - restore register configuration */ +static void pch_phub_restore_reg_conf (struct pci_dev *pdev) +{ +unsigned int i; +void __iomem *p = pch_phub_reg.pch_phub_base_address; + +dev_dbg (&pdev->dev,"pch_phub_restore_reg_conf ENTRY\n" ); +iowrite32 (pch_phub_reg.phub_id_reg, p +PCH_PHUB_ID_REG ); +iowrite32 (pch_phub_reg.q_pri_val_reg, p +PCH_PHUB_QUEUE_PRI_VAL_REG ); +iowrite32 (pch_phub_reg.rc_q_maxsize_reg, + p +PCH_PHUB_RC_QUEUE_MAXSIZE_REG ); +iowrite32 (pch_phub_reg.bri_q_maxsize_reg, + p +PCH_PHUB_BRI_QUEUE_MAXSIZE_REG ); +iowrite32 (pch_phub_reg.comp_resp_timeout_reg, + p +PCH_PHUB_COMP_RESP_TIMEOUT_REG ); +iowrite32 (pch_phub_reg.bus_slave_control_reg, + p +PCH_PHUB_BUS_SLAVE_CONTROL_REG ); +iowrite32 (pch_phub_reg.deadlock_avoid_type_reg, + p +PCH_PHUB_DEADLOCK_AVOID_TYPE_REG ); +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg0, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG0 ); +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg1, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG1 ); +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg2, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG2 ); +iowrite32 (pch_phub_reg.intpin_reg_wpermit_reg3, + p +PCH_PHUB_INTPIN_REG_WPERMIT_REG3 ); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.phub_id_reg=%x, " +"pch_phub_reg.q_pri_val_reg=%x, " +"pch_phub_reg.rc_q_maxsize_reg=%x, " +"pch_phub_reg.bri_q_maxsize_reg=%x, " +"pch_phub_reg.comp_resp_timeout_reg=%x, " +"pch_phub_reg.bus_slave_control_reg=%x, " +"pch_phub_reg.deadlock_avoid_type_reg=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg0=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg1=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg2=%x, " +"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n" , + pch_phub_reg.phub_id_reg, + pch_phub_reg.q_pri_val_reg, + pch_phub_reg.rc_q_maxsize_reg, + pch_phub_reg.bri_q_maxsize_reg, + pch_phub_reg.comp_resp_timeout_reg, + pch_phub_reg.bus_slave_control_reg, + pch_phub_reg.deadlock_avoid_type_reg, + pch_phub_reg.intpin_reg_wpermit_reg0, + pch_phub_reg.intpin_reg_wpermit_reg1, + pch_phub_reg.intpin_reg_wpermit_reg2, + pch_phub_reg.intpin_reg_wpermit_reg3); +for (i =0 ; i <MAX_NUM_INT_REDUCE_CONTROL_REG ; i++) { +iowrite32 (pch_phub_reg.int_reduce_control_reg[i], + p +PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE +4 * i); +dev_dbg (&pdev->dev,"pch_phub_save_reg_conf : " +"pch_phub_reg.int_reduce_control_reg[%d]=%x\n" , + i, pch_phub_reg.int_reduce_control_reg[i]); + } + +iowrite32 (pch_phub_reg.clkcfg_reg, p +CLKCFG_REG_OFFSET ); +} + +/** +* pch_phub_read_serial_rom() - Reading Serial ROM +* @offset_address: Serial ROM offset address to read. +* @data: Read buffer for specified Serial ROM value. +*/ +static void pch_phub_read_serial_rom (unsigned int offset_address,u8 *data) +{ +void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address + + offset_address; + + *data =ioread8 (mem_addr); +} + +/** +* pch_phub_write_serial_rom() - Writing Serial ROM +* @offset_address: Serial ROM offset address. +* @data: Serial ROM value to write. +*/ +static int pch_phub_write_serial_rom (unsigned int offset_address,u8 data) +{ +void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address + + (offset_address &PCH_WORD_ADDR_MASK ); +int i; +unsigned int word_data; +unsigned int pos; +unsigned int mask; + pos = (offset_address %4 ) *8 ; + mask = ~(0xFF << pos); +
drivers/char/pch_phub/pch_phub.c line 269
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+iowrite32 (PCH_PHUB_ROM_WRITE_ENABLE , + pch_phub_reg.pch_phub_extrom_base_address + +PHUB_CONTROL ); + + word_data =ioread32 (mem_addr); +iowrite32 ((word_data & mask) | (u32 )data << pos, mem_addr); + + i =0 ; +while (0x00 !=ioread8 (pch_phub_reg.pch_phub_extrom_base_address + +PHUB_STATUS )) {
We prefer to have constant on right side of comparison...
Quoted 17 lines
drivers/char/pch_phub/pch_phub.c new file +17
-0+msleep (1 ); +if (PHUB_TIMEOUT == i) +return -EPERM ; + i++; + } + +iowrite32 (PCH_PHUB_ROM_WRITE_DISABLE , + pch_phub_reg.pch_phub_extrom_base_address + +PHUB_CONTROL ); + +return 0 ; +} + +/** +* pch_phub_read_serial_rom_val() - Read Serial ROM value +* @offset_address: Serial ROM address offset value. +* @data: Serial ROM value to read.
drivers/char/pch_phub/pch_phub.c line 296
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+*/ +static void pch_phub_read_serial_rom_val (unsigned int offset_address,u8 *data) +{ +unsigned int mem_addr; + + mem_addr =PCH_PHUB_ROM_START_ADDR + + pch_phub_mac_offset[offset_address]; + +pch_phub_read_serial_rom (mem_addr, data); +
drop blank line above.
Quoted 60 lines
drivers/char/pch_phub/pch_phub.c new file +60
-0+} + + +/** +* pch_phub_write_serial_rom_val() - writing Serial ROM value +* @offset_address: Serial ROM address offset value. +* @data: Serial ROM value. +*/ +static int pch_phub_write_serial_rom_val (unsigned int offset_address,u8 data) +{ +int retval; +unsigned int mem_addr; + + mem_addr =PCH_PHUB_ROM_START_ADDR + + pch_phub_mac_offset[offset_address]; + + retval =pch_phub_write_serial_rom (mem_addr, data); + +return retval; +} + +/* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration +* for Gigabit Ethernet MAC address +*/ +static int pch_phub_gbe_serial_rom_conf (void ) +{ +int retval; + + retval =pch_phub_write_serial_rom (0x0b ,0xbc ); + retval |=pch_phub_write_serial_rom (0x0a ,0x10 ); + retval |=pch_phub_write_serial_rom (0x09 ,0x01 ); + retval |=pch_phub_write_serial_rom (0x08 ,0x02 ); + + retval |=pch_phub_write_serial_rom (0x0f ,0x00 ); + retval |=pch_phub_write_serial_rom (0x0e ,0x00 ); + retval |=pch_phub_write_serial_rom (0x0d ,0x00 ); + retval |=pch_phub_write_serial_rom (0x0c ,0x80 ); + + retval |=pch_phub_write_serial_rom (0x13 ,0xbc ); + retval |=pch_phub_write_serial_rom (0x12 ,0x10 ); + retval |=pch_phub_write_serial_rom (0x11 ,0x01 ); + retval |=pch_phub_write_serial_rom (0x10 ,0x18 ); + + retval |=pch_phub_write_serial_rom (0x1b ,0xbc ); + retval |=pch_phub_write_serial_rom (0x1a ,0x10 ); + retval |=pch_phub_write_serial_rom (0x19 ,0x01 ); + retval |=pch_phub_write_serial_rom (0x18 ,0x19 ); + + retval |=pch_phub_write_serial_rom (0x23 ,0xbc ); + retval |=pch_phub_write_serial_rom (0x22 ,0x10 ); + retval |=pch_phub_write_serial_rom (0x21 ,0x01 ); + retval |=pch_phub_write_serial_rom (0x20 ,0x3a ); + + retval |=pch_phub_write_serial_rom (0x27 ,0x01 ); + retval |=pch_phub_write_serial_rom (0x26 ,0x00 ); + retval |=pch_phub_write_serial_rom (0x25 ,0x00 ); + retval |=pch_phub_write_serial_rom (0x24 ,0x00 ); + +return retval; +}
drivers/char/pch_phub/pch_phub.c line 366
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +/** +* pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address +* @offset_address: Gigabit Ethernet MAC address offset value. +* @data: Buffer of the Gigabit Ethernet MAC address value. +*/ +static void pch_phub_read_gbe_mac_addr (u8 *data) +{ +int i; +for (i =0 ; i <6 ; i++)
s/6/ETH_ALEN/
(see below)
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+pch_phub_read_serial_rom_val (i, &data[i]); +} + +/** +* pch_phub_write_gbe_mac_addr() - Write MAC address +* @offset_address: Gigabit Ethernet MAC address offset value. +* @data: Gigabit Ethernet MAC address value. +*/
drivers/char/pch_phub/pch_phub.c line 384
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+static int pch_phub_write_gbe_mac_addr (u8 *data) +{ +int retval; +int i; + + retval =pch_phub_gbe_serial_rom_conf (); +if (retval) +return retval; + +for (i =0 ; i <6 ; i++) {
s/6/ETH_ALEN/
(see below)
Quoted 48 lines
drivers/char/pch_phub/pch_phub.c new file +48
-0+ retval =pch_phub_write_serial_rom_val (i, data[i]); +if (retval) +return retval; + } + +return retval; +} + +static ssize_t pch_phub_read (struct file *file,char __user *buf,size_t size, +loff_t *ppos) +{ +unsigned int rom_signature; +unsigned char rom_length; +int ret_value; +unsigned int tmp; +unsigned char data; +unsigned int addr_offset; +unsigned int orom_size; +int ret; +int err; +loff_t pos = *ppos; + + ret =mutex_lock_interruptible (&pch_phub_read_mutex); +if (ret) { + err = -ERESTARTSYS ; + goto return_err_nomutex; + } + +/* Get Rom signature */ +pch_phub_read_serial_rom (0x80 , (unsigned char *)&rom_signature); + rom_signature &=0xff ; +pch_phub_read_serial_rom (0x81 , (unsigned char *)&tmp); + rom_signature |= (tmp &0xff ) <<8 ; +if (rom_signature ==0xAA55 ) { +pch_phub_read_serial_rom (0x82 , &rom_length); + orom_size = rom_length *512 ; +if (orom_size < pos) { + addr_offset =0 ; + goto return_ok; + } + +for (addr_offset =0 ; addr_offset < size; addr_offset++) { +pch_phub_read_serial_rom (0x80 + addr_offset + pos, + &data); + ret_value =copy_to_user (&buf[addr_offset], &data,1 ); +if (ret_value) { + err = -EFAULT ; + goto return_err;
drivers/char/pch_phub/pch_phub.c line 442
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ } + +if (orom_size < pos + addr_offset) { + *ppos += addr_offset; + goto return_ok; + } + + } + }else { +return -ENODATA ;
Need to unlock mutex here also??
Quoted 61 lines
drivers/char/pch_phub/pch_phub.c new file +61
-0+ } + *ppos += addr_offset; +return_ok: +mutex_unlock (&pch_phub_read_mutex); +return addr_offset; + +return_err: +mutex_unlock (&pch_phub_read_mutex); +return_err_nomutex: +return err; +} + + +static ssize_t pch_phub_write (struct file *file,const char __user *buf, +size_t size,loff_t *ppos) +{ +unsigned int data; +int ret_value1; +int ret_value2; +int err; +unsigned int addr_offset; +loff_t pos = *ppos; +int ret; + + ret =mutex_lock_interruptible (&pch_phub_write_mutex); +if (ret) { + err = -ERESTARTSYS ; + goto return_err_nomutex; + } + +for (addr_offset =0 ; addr_offset < size; addr_offset++) { + ret_value1 =get_user (data, &buf[addr_offset]); +if (ret_value1) { + err = -EFAULT ; + goto return_err; + } + + ret_value2 =pch_phub_write_serial_rom (0x80 + addr_offset + pos, + data); +if (ret_value2) { + err = ret_value2; + goto return_err; + } + +if (PCH_PHUB_OROM_SIZE < pos + addr_offset) { + *ppos += addr_offset; + goto return_ok; + } + + } + + *ppos += addr_offset; + +return_ok: +mutex_unlock (&pch_phub_write_mutex); +return addr_offset; + +return_err: +mutex_unlock (&pch_phub_write_mutex); +return_err_nomutex: +return err;
drivers/char/pch_phub/pch_phub.c line 513
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+} + + +static long pch_phub_ioctl (struct file *file,unsigned int cmd, +unsigned long arg) +{ +int ret_value; +int ret; +int rtn; +__u8 mac_addr[6 ];
#include <linux/if_ether.h>
__u8 mac_addr[ETH_ALEN];
Quoted 8 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+void __user *varg = (void __user *)arg; + + ret =mutex_lock_interruptible (&pch_phub_ioctl_mutex); +if (ret) { + ret_value = -ERESTARTSYS ; + goto return_nomutex; + } +
drivers/char/pch_phub/pch_phub.c line 531
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+if (pch_phub_reg.pch_phub_suspended == true) { + ret_value = -EBUSY ; + goto return_ioctrl; + } + +switch (cmd) { +case IOCTL_PHUB_READ_MAC_ADDR : +pch_phub_read_gbe_mac_addr (mac_addr); + + ret_value =copy_to_user (varg, mac_addr,sizeof (mac_addr));
s/sizeof(mac_addr)/ETH_ALEN/
drivers/char/pch_phub/pch_phub.c line 535
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+break ; + +case IOCTL_PHUB_WRITE_MAC_ADDR : + rtn =copy_from_user (mac_addr, varg,sizeof (mac_addr));
ditto.
Quoted 114 lines
drivers/char/pch_phub/pch_phub.c new file +112
-0+ +if (rtn) { + ret_value = -EFAULT ; +break ; + } + + ret_value =pch_phub_write_gbe_mac_addr (mac_addr); +break ; + +default : + ret_value = -EINVAL ; +break ; + } +return_ioctrl: +mutex_unlock (&pch_phub_ioctl_mutex); +return_nomutex: +return ret_value; +} +static int __devinit pch_phub_probe (struct pci_dev *pdev, +const struct pci_device_id *id) +{ +int ret; +unsigned int rom_size; + + ret =pci_enable_device (pdev); +if (ret) { +dev_dbg (&pdev->dev, +"pch_phub_probe : pci_enable_device FAILED(ret=%d)" , ret); + goto err_pci_enable_dev; + } +dev_dbg (&pdev->dev,"pch_phub_probe : pci_enable_device returns %d\n" , + ret); + + ret =pci_request_regions (pdev,MODULE_NAME ); +if (ret) { +dev_dbg (&pdev->dev, +"pch_phub_probe : pci_request_regions FAILED(ret=%d)" , ret); + goto err_req_regions; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_request_regions returns %d\n" , ret); + + pch_phub_reg.pch_phub_base_address =pci_iomap (pdev,1 ,0 ); + +if (pch_phub_reg.pch_phub_base_address ==0 ) { +dev_dbg (&pdev->dev,"pch_phub_probe : pci_iomap FAILED" ); + ret = -ENOMEM ; + goto err_pci_iomap; + } +dev_dbg (&pdev->dev,"pch_phub_probe : pci_iomap SUCCESS and value " +"in pch_phub_base_address variable is 0x%08x\n" , + (unsigned int )pch_phub_reg.pch_phub_base_address); + + pch_phub_reg.pch_phub_extrom_base_address = +pci_map_rom (pdev, &rom_size); +if (pch_phub_reg.pch_phub_extrom_base_address ==0 ) { +dev_dbg (&pdev->dev,"pch_phub_probe : pci_map_rom FAILED" ); + ret = -ENOMEM ; + goto err_pci_map; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"pci_map_rom SUCCESS and value in " +"pch_phub_extrom_base_address variable is 0x%08x\n" , + (unsigned int )pch_phub_reg.pch_phub_extrom_base_address); + + ret =alloc_chrdev_region (&pch_phub_dev_no,0 , +PCH_MINOR_NOS ,MODULE_NAME ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : " +"alloc_chrdev_region FAILED(ret=%d)" , ret); + + goto err_alloc_cdev; + } +dev_dbg (&pdev->dev,"pch_phub_probe : " +"alloc_chrdev_region returns %d\n" , ret); + +cdev_init (&pch_phub_dev, &pch_phub_fops); +dev_dbg (&pdev->dev, +"pch_phub_probe : cdev_init invoked successfully\n" ); + + pch_phub_dev.owner =THIS_MODULE ; + pch_phub_dev.ops = &pch_phub_fops; + + ret =cdev_add (&pch_phub_dev, pch_phub_dev_no,PCH_MINOR_NOS ); +if (ret) { +dev_dbg (&pdev->dev,"pch_phub_probe : cdev_add FAILED(ret=%d)" , + ret); + goto err_cdev_add; + } +dev_dbg (&pdev->dev,"pch_phub_probe : cdev_add returns %d\n" , ret); + +/* set the clock config reg if CAN clock is 50Mhz */ +dev_dbg (&pdev->dev,"pch_phub_probe : invoking " +"pch_phub_read_modify_write_reg " +"to set CLKCFG reg for CAN clk 50Mhz\n" ); +pch_phub_read_modify_write_reg ((unsigned int )CLKCFG_REG_OFFSET , +CLKCFG_CAN_50MHZ ,CLKCFG_CANCLK_MASK ); + +/* set the prefech value */ +iowrite32 (0x000ffffa , pch_phub_reg.pch_phub_base_address +0x14 ); +/* set the interrupt delay value */ +iowrite32 (0x25 , pch_phub_reg.pch_phub_base_address +0x44 ); +return 0 ; + +err_cdev_add: +unregister_chrdev_region (pch_phub_dev_no,PCH_MINOR_NOS ); +err_alloc_cdev: +pci_unmap_rom (pdev, pch_phub_reg.pch_phub_extrom_base_address); +err_pci_map: +pci_iounmap (pdev, pch_phub_reg.pch_phub_base_address); +err_pci_iomap: +pci_release_regions (pdev);
drivers/char/pch_phub/pch_phub.c line 669
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+err_req_regions: +pci_disable_device (pdev); +err_pci_enable_dev: +dev_dbg (&pdev->dev,"pch_phub_probe returns %d\n" , ret); +return ret; +} + +static void __devexit pch_phub_remove(struct pci_dev *pdev) +{ +
drop blank line.
Quoted 21 lines
drivers/char/pch_phub/pch_phub.c new file +21
-0+cdev_del (&pch_phub_dev); +dev_dbg (&pdev->dev, +"pch_phub_remove - cdev_del Invoked successfully\n" ); + +unregister_chrdev_region (pch_phub_dev_no,PCH_MINOR_NOS ); +dev_dbg (&pdev->dev,"pch_phub_remove - " +"unregister_chrdev_region Invoked successfully\n" ); + +pci_unmap_rom (pdev, pch_phub_reg.pch_phub_extrom_base_address); + +pci_iounmap (pdev, pch_phub_reg.pch_phub_base_address); + +dev_dbg (&pdev->dev,"pch_phub_remove - " +"pci_iounmap Invoked successfully\n" ); + +pci_release_regions (pdev); +dev_dbg (&pdev->dev,"pch_phub_remove - " +"pci_release_regions Invoked successfully\n" ); + +pci_disable_device (pdev); + dev_dbg(&pdev->dev, "pch_phub_remove - "
drivers/char/pch_phub/pch_phub.c line 733
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+ "pci_disable_device Invoked successfully\n"); + +} + +#ifdef CONFIG_PM + +static int pch_phub_resume (struct pci_dev *pdev) +{ +
drop that blank line before the local data, but leave the one after local data.
Quoted 9 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+int ret; + +pci_set_power_state (pdev,PCI_D0 ); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_set_power_state Invoked successfully\n" ); + +pci_restore_state (pdev); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_restore_state Invoked successfully\n" );
drivers/char/pch_phub/pch_phub.c line 752
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ + ret =pci_enable_device (pdev); +if (ret) { +dev_dbg (&pdev->dev, +"pch_phub_resume-pci_enable_device failed(ret=%d) " , ret); +return ret; + } + +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_enable_device returns -%d\n" , ret);
The '-' before %d could be confusing.
drivers/char/pch_phub/pch_phub.c line 764
Quoted 12 lines
drivers/char/pch_phub/pch_phub.c new file +12
-0+ +pci_enable_wake (pdev, PCI_D3hot,0 ); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pci_enable_wake Invoked successfully\n" ); + +pch_phub_restore_reg_conf (pdev); +dev_dbg (&pdev->dev,"pch_phub_resume - " +"pch_phub_restore_reg_conf Invoked successfully\n" ); + + pch_phub_reg.pch_phub_suspended = false; + +dev_dbg (&pdev->dev,"pch_phub_resume returns- %d\n" ,0 );
All of these dev_dbg() calls should use __func__ to get the function name:
dev_dbg(&pdev->dev, "%s returns: %d\n", __func__, 0);
(same for other functions)
(I dropped the '-' so that it won't look like a negative number.)
Quoted 16 lines
drivers/char/pch_phub/pch_phub.c new file +16
-0+return 0 ; +} +#else +#define pch_phub_suspend NULL +#define pch_phub_resume NULL +#endif /* CONFIG_PM */ + +static struct pci_device_id pch_phub_pcidev_id[] = { + + {PCI_DEVICE (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_PCH1_PHUB )}, + {0 ,} +}; + + +static struct pci_driver pch_phub_driver = { + .name ="pch_phub" ,
drivers/char/pch_phub/pch_phub.c line 790
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ .id_table = pch_phub_pcidev_id, + .probe = pch_phub_probe, + .remove = __devexit_p(pch_phub_remove), + .suspend = pch_phub_suspend, + .resume = pch_phub_resume +}; + +/* pch_phub_pci_init - Implements the initialization functionality of +* the module. +*/
drop obvious comments.
drivers/char/pch_phub/pch_phub.c line 799
Quoted 9 lines
drivers/char/pch_phub/pch_phub.c new file +9
-0+static int __init pch_phub_pci_init (void ) +{ +int ret; + ret =pci_register_driver (&pch_phub_driver); + +return ret; +} + +/* pch_phub_pci_exit - Implements the exit functionality of the module. */
drop obvious comment.
drivers/char/pch_phub/pch_phub.c line 803
Quoted 4 lines
drivers/char/pch_phub/pch_phub.c new file +4
-0+static void __exit pch_phub_pci_exit(void) +{ +pci_unregister_driver (&pch_phub_driver); +
drop blank line.
Quoted 15 lines
drivers/char/pch_phub/pch_phub.c new file +8
-0+} + +module_init (pch_phub_pci_init); +module_exit (pch_phub_pci_exit); + +MODULE_DESCRIPTION ("PCH PACKET HUB PCI Driver" ); +MODULE_LICENSE ("GPL" ); +drivers/char/pch_phub/pch_phub.h new file +0
-0
drivers/char/pch_phub/pch_phub.h line 3
Quoted 3 lines
drivers/char/pch_phub/pch_phub.h new file +3
-0@@ -0,0 +1,48 @@ +#ifndef __PCH_PHUB_H__ +#define __PCH_PHUB_H__ +/*!
??
Quoted 7 lines
drivers/char/pch_phub/pch_phub.h new file +7
-0+* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful,
drivers/char/pch_phub/pch_phub.h line 20
Quoted 10 lines
drivers/char/pch_phub/pch_phub.h new file +10
-0+* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +*/ + +#define PHUB_IOCTL_MAGIC (0xf7)
ioctl numbers need to be added to Documentation/ioctl/ioctl-number.txt, please.
Quoted 28 lines
drivers/char/pch_phub/pch_phub.h new file +28
-0+ +/* Read GbE MAC address */ +#define IOCTL_PHUB_READ_MAC_ADDR (_IOR(PHUB_IOCTL_MAGIC, 6, __u8[6])) + +/* Write GbE MAC address */ +#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, __u8[6])) + +/* SROM ACCESS Macro */ +#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) + +/* Registers address offset */ +#define PCH_PHUB_ID_REG 0x0000 +#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004 +#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008 +#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C +#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010 +#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014 +#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028 +#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C +#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040 +#define CLKCFG_REG_OFFSET 0x500 + +#define PCH_PHUB_OROM_SIZE 15360 + +#endif
Signature · 2 lines
~Randy *** Remember to use Documentation/SubmitChecklist when testing your code ***
PATCH 1/1 Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakHi Randy
I have modified for your comments.
Please confirm below.
Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
--- Documentation/ioctl/ioctl-number.txt | 1 + drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 803 ++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 ++ 6 files changed, 866 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
Documentation/ioctl/ioctl-number.txt +1 -0
@@ -320,4 +320,5 @@ Code Seq#(hex) Include File Comments <mailto:[email protected]> 0xF4 00-1F video/mbxfb.h mbxfb <mailto:[email protected]> +0xF7 00-0F drivers/char/pch_phub/pch_phub.h PCH Phub driver 0xFD all linux/dm-ioctl.h
drivers/char/Kconfig +9 -0
@@ -4,6 +4,15 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + This driver is for PCH PHUB of Topcliff which is an IOH for x86 + embedded processor. The Topcliff has MAC address and Option ROM data + in SROM. This driver can access MAC address and Option ROM data in + SROM. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +803 -0
803 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +48 -0
48 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Arnd Bergmann
maintainerRe: [PATCH] Packet hub driver of Topcliff PCH
I took another look and found some more things that should be improved. Overall, the quality of this driver has improved enourmously, and I'm optimistic that it will be a lot easier for you in your next device driver with all the details you have learned about the coding style.
Quoted 8 lines · Masayuki Ohtak
drivers/char/pch_phub/pch_phub.c new file +8
-0+struct pch_phub_reg { +u32 phub_id_reg; +u32 q_pri_val_reg; +u32 rc_q_maxsize_reg; +u32 bri_q_maxsize_reg; +u32 comp_resp_timeout_reg; +u32 bus_slave_control_reg; +u32 deadlock_avoid_type_reg;
drivers/char/pch_phub/pch_phub.c line 84
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+u32 intpin_reg_wpermit_reg0; +u32 intpin_reg_wpermit_reg1; +u32 intpin_reg_wpermit_reg2; +u32 intpin_reg_wpermit_reg3; +u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG ]; +u32 clkcfg_reg; +void __iomem *pch_phub_base_address; +void __iomem *pch_phub_extrom_base_address; +int pch_phub_suspended; +} pch_phub_reg;
The variable you define here is in the global namespace, which it should not be in. I'd suggest making it static and splitting the type defintion from the variable definition to make that more obvious, like:
struct pch_phub_reg {
...
};static struct pch_phub_reg pch_phub_reg;
drivers/char/pch_phub/pch_phub.c line 91
Quoted 3 lines
drivers/char/pch_phub/pch_phub.c new file +3
-0+static DEFINE_MUTEX (pch_phub_ioctl_mutex); +static DEFINE_MUTEX (pch_phub_read_mutex); +static DEFINE_MUTEX (pch_phub_write_mutex);
Having three mutexes here means that you have effectively no serialization between the functions at all. The mutex only has an effect if you use the same one in all three functions!
Arnd
Re: [PATCH] Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakQuoted 4 lines · Masayuki Ohtak
Hi Randy
I have modified for your comments.
Please confirm below.
Agreed, thanks for the updates.
Quoted 42 lines
Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.Signed-off-by Masayuki Ohtake <[email protected]>Acked-by Arnd Bergmann <[email protected]>--- Documentation/ioctl/ioctl-number.txt | 1 + drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 803 ++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 ++ 6 files changed, 866 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.hDocumentation/ioctl/ioctl-number.txt +1
-0@@ -320,4 +320,5 @@ Code Seq#(hex) Include File Comments <mailto:[email protected]> 0xF4 00-1F video/mbxfb.h mbxfb <mailto:[email protected]> +0xF7 00-0F drivers/char/pch_phub/pch_phub.h PCH Phub driver 0xFD all linux/dm-ioctl.h
Signature · 2 lines
~Randy *** Remember to use Documentation/SubmitChecklist when testing your code ***
PATCH 1/1 Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakHi Arnd
I have modified for your comments.
Please confirm below.
Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
--- Documentation/ioctl/ioctl-number.txt | 1 + drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 802 ++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 ++ 6 files changed, 865 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
Documentation/ioctl/ioctl-number.txt +1 -0
@@ -320,4 +320,5 @@ Code Seq#(hex) Include File Comments <mailto:[email protected]> 0xF4 00-1F video/mbxfb.h mbxfb <mailto:[email protected]> +0xF7 00-0F drivers/char/pch_phub/pch_phub.h PCH Phub driver 0xFD all linux/dm-ioctl.h
drivers/char/Kconfig +9 -0
@@ -4,6 +4,15 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + This driver is for PCH PHUB of Topcliff which is an IOH for x86 + embedded processor. The Topcliff has MAC address and Option ROM data + in SROM. This driver can access MAC address and Option ROM data in + SROM. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +802 -0
802 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +48 -0
48 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Arnd Bergmann
maintainerRe: [PATCH] Packet hub driver of Topcliff PCH
Quoted 5 lines · On Tuesday 06 July 2010 08:20:52 Masayuki Ohtak wrote:
Hi Arnd
I have modified for your comments.
Please confirm below.
Yes, looks good. Thanks for the quick reply.
Arnd
Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 10 lines · Arnd Bergmann
Quoted 5 lines · On Tuesday 06 July 2010 08:20:52 Masayuki Ohtak wrote:
Hi Arnd
I have modified for your comments.
Please confirm below.Yes, looks good. Thanks for the quick reply.
Arnd
Hi Andrew,
Do you have any further comments on this patch? If so, please let us know.
Thanks
-Yong
Re: [PATCH] Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakQuoted 10 lines · On Tue, 06 Jul 2010 15:20:52 +0900 Masayuki Ohtak <[email protected]>…
Hi Arnd
I have modified for your comments.
Please confirm below.Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Quoted 10 lines
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
That didn't describe the most important part of the driver: the userspace interface. We should add here something along the lines of
The driver creates a character device /dev/pch_phub. That device file supports the following operations:
read(): <document the read operation - seems to read a serial ROM?> write():<document the write operation - seems to write a serial ROM?> ioctl():<document the ioctl operation - seems to read/write a MAC address?>
Quoted 19 lines
...
drivers/char/pch_phub/pch_phub.c new file +16
-0+static ssize_t pch_phub_write (struct file *file,const char __user *buf, +size_t size,loff_t *ppos) +{ +unsigned int data; +int ret_value1; +int ret_value2; +int err; +unsigned int addr_offset; +loff_t pos = *ppos; +int ret; + + ret =mutex_lock_interruptible (&pch_phub_mutex); +if (ret) { + err = -ERESTARTSYS ; + goto return_err_nomutex; + }
drivers/char/pch_phub/pch_phub.c line 480
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +for (addr_offset =0 ; addr_offset < size; addr_offset++) { + ret_value1 =get_user (data, &buf[addr_offset]); +if (ret_value1) { + err = -EFAULT ; + goto return_err; + } + + ret_value2 =pch_phub_write_serial_rom (0x80 + addr_offset + pos, + data);
I suspect this function will do strange things if passed an initial *ppos which is outside the range of the ROM. It looks like it will write a single byte into the ROM then will bale out.
drivers/char/pch_phub/pch_phub.c line 486
Quoted 6 lines
drivers/char/pch_phub/pch_phub.c new file +6
-0+if (ret_value2) { + err = ret_value2; + goto return_err; + } + +if (PCH_PHUB_OROM_SIZE < pos + addr_offset) {
Is this off-by-one?
Quoted 20 lines
drivers/char/pch_phub/pch_phub.c new file +17
-0+ *ppos += addr_offset; + goto return_ok; + } + + } + + *ppos += addr_offset; + +return_ok: +mutex_unlock (&pch_phub_mutex); +return addr_offset; + +return_err: +mutex_unlock (&pch_phub_mutex); +return_err_nomutex: +return err; +}
Re: [PATCH] Packet hub driver of Topcliff PCH
Hi Andrew Morton
Quoted 6 lines
The driver creates a character device
/dev/pch_phub. That device file supports the following operations:
read(): <document the read operation - seems to read a serial ROM?> write():<document the write operation - seems to write a serial ROM?> ioctl():<document the ioctl operation - seems to read/write a MAC address?>
We will add the above.
Quoted 5 lines
I suspect this function will do strange things if passed an initial *ppos which is outside the range of the ROM. It looks like it will write a single byte into the ROM then will bale out.
Quoted 8 lines
Quoted 6 lines
+ if (
ret_value2) {
+ err =ret_value2;
+ gotoreturn_err;
+ }
+
+ if (PCH_PHUB_OROM_SIZE< pos +addr_offset) {Is this off-by-one?
I understand OROM upper size check is not enough. If the my understanding true, We will modify like below. Can you accept the following our modification ?
+static ssize_t pch_phub_write(struct file *file, const char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ unsigned int data;
+ int ret_value1;
+ int ret_value2;
+ int err;
+ unsigned int addr_offset;
+ loff_t pos = *ppos;
+ int ret;
+
+ ret = mutex_lock_interruptible(&pch_phub_mutex);
+ if (ret) {
+ err = -ERESTARTSYS;
+ goto return_err_nomutex;
+ }
+
+ for (addr_offset = 0; addr_offset < size; addr_offset++) {
+ if (PCH_PHUB_OROM_SIZE < pos + addr_offset) {
+ *ppos += addr_offset;
+ goto return_ok;
+ }
+ ret_value1 = get_user(data, &buf[addr_offset]);
+ if (ret_value1) {
+ err = -EFAULT;
+ goto return_err;
+ }
+
+ ret_value2 = pch_phub_write_serial_rom(0x80 + addr_offset + pos,
+ data);
+ if (ret_value2) {
+ err = ret_value2;
+ goto return_err;
+ }
+
Thanks, Ohtake
----- Original Message -----
From: "Andrew Morton" <[email protected]>
To: "Masayuki Ohtak" <[email protected]>
Cc: "Arnd Bergmann" <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>; <[email protected]>; "Alan Cox" <[email protected]>; "LKML" <[email protected]>
Sent: Saturday, July 10, 2010 5:00 AM
Subject: Re: [PATCH] Packet hub driver of Topcliff PCH
Quoted 99 lines
Quoted 10 lines · On Tue, 06 Jul 2010 15:20:52 +0900 Masayuki Ohtak <[email protected]>…
Hi Arnd
I have modified for your comments.
Please confirm below.Thanks, Ohtake.
---
Packet hub driver of Topcliff PCHQuoted 10 lines
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.That didn't describe the most important part of the driver: the userspace interface. We should add here something along the lines of
The driver creates a character device
/dev/pch_phub. That device file supports the following operations:
read(): <document the read operation - seems to read a serial ROM?> write():<document the write operation - seems to write a serial ROM?> ioctl():<document the ioctl operation - seems to read/write a MAC address?>Quoted 19 lines
...
drivers/char/pch_phub/pch_phub.c new file +16
-0+static ssize_t pch_phub_write (struct file *file,const char __user *buf, +size_t size,loff_t *ppos) +{ +unsigned int data; +int ret_value1; +int ret_value2; +int err; +unsigned int addr_offset; +loff_t pos = *ppos; +int ret; + + ret =mutex_lock_interruptible (&pch_phub_mutex); +if (ret) { + err = -ERESTARTSYS ; + goto return_err_nomutex; + }drivers/char/pch_phub/pch_phub.c line 480
Quoted 10 lines
drivers/char/pch_phub/pch_phub.c new file +10
-0+ +for (addr_offset =0 ; addr_offset < size; addr_offset++) { + ret_value1 =get_user (data, &buf[addr_offset]); +if (ret_value1) { + err = -EFAULT ; + goto return_err; + } + + ret_value2 =pch_phub_write_serial_rom (0x80 + addr_offset + pos, + data);I suspect this function will do strange things if passed an initial *ppos which is outside the range of the ROM. It looks like it will write a single byte into the ROM then will bale out.
Quoted 6 lines
+ if (
ret_value2) {
+ err =ret_value2;
+ gotoreturn_err;
+ }
+
+ if (PCH_PHUB_OROM_SIZE< pos +addr_offset) {Is this off-by-one?
Quoted 20 lines
+ *ppos +=
addr_offset;
+ gotoreturn_ok;
+ }drivers/char/pch_phub/pch_phub.c new file +14
-0+ + } + + *ppos += addr_offset; + +return_ok: +mutex_unlock (&pch_phub_mutex); +return addr_offset; + +return_err: +mutex_unlock (&pch_phub_mutex); +return_err_nomutex: +return err; +}
PATCH 1/1 Packet hub driver of Topcliff PCH
In reply to Masayuki OhtakHi Andrew Morton
We have modified our packet hub driver for your indication. Please confirm below.
Thanks, Ohtake.
---
Packet hub driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Packet hub is a special converter device in Topcliff PCH that translate AMBA transactions to PCI Express transactions and vice versa. Thus packet hub helps present all IO peripherals in Topcliff PCH as PCIE devices to IA system. Topcliff PCH has MAC address and Option ROM data.
These data are in SROM which is connected to PCIE bus.
Packet hub driver of Topcliff PCH can access MAC address and Option ROM data in SROM.
The driver creates a character device /dev/pch_phub. That device file supports the following operations:
read() :Read Option ROM data of SROM
write():Write Option ROM data of SROM
ioctl():Read/Write MAC address of SROM
--- Documentation/ioctl/ioctl-number.txt | 1 + drivers/char/Kconfig | 9 + drivers/char/Makefile | 2 + drivers/char/pch_phub/Makefile | 3 + drivers/char/pch_phub/pch_phub.c | 800 ++++++++++++++++++++++++++++++++++ drivers/char/pch_phub/pch_phub.h | 48 ++ 6 files changed, 863 insertions(+), 0 deletions(-) create mode 100644 drivers/char/pch_phub/Makefile create mode 100755 drivers/char/pch_phub/pch_phub.c create mode 100755 drivers/char/pch_phub/pch_phub.h
Documentation/ioctl/ioctl-number.txt +1 -0
@@ -320,4 +320,5 @@ Code Seq#(hex) Include File Comments <mailto:[email protected]> 0xF4 00-1F video/mbxfb.h mbxfb <mailto:[email protected]> +0xF7 00-0F drivers/char/pch_phub/pch_phub.h PCH Phub driver 0xFD all linux/dm-ioctl.h
drivers/char/Kconfig +9 -0
@@ -4,6 +4,15 @@ menu "Character devices" +config PCH_PHUB + tristate "PCH PHUB" + depends on PCI + help + This driver is for PCH PHUB of Topcliff which is an IOH for x86 + embedded processor. The Topcliff has MAC address and Option ROM data + in SROM. This driver can access MAC address and Option ROM data in + SROM. + config VT bool "Virtual terminal" if EMBEDDED depends on !S390
drivers/char/Makefile +2 -0
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o +obj-$(CONFIG_PCH_PHUB) += pch_phub/ + # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c
drivers/char/pch_phub/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o + +pch_phub_drv-objs := pch_phub.o
drivers/char/pch_phub/pch_phub.c new file +800 -0
800 lines not on this page · raw message
drivers/char/pch_phub/pch_phub.h new file +48 -0
48 lines not on this page · raw message
Signature · 1 line
1.6.0.6
PATCH 1/1 I2C driver of Topcliff PCH
In reply to Masayuki OhtakI2C driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Topcliff PCH has I2C I/F. Using this I/F, it is able to access system devices connected to I2C.
--- drivers/i2c/busses/Kconfig | 8 + drivers/i2c/busses/Makefile | 3 + drivers/i2c/busses/i2c-pch.c | 1390 ++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-pch.h | 147 +++++ drivers/i2c/i2c-dev.c | 28 + 5 files changed, 1576 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-pch.c create mode 100644 drivers/i2c/busses/i2c-pch.h
drivers/i2c/busses/Kconfig +8 -0
@@ -7,6 +7,14 @@ menu "I2C Hardware Bus support" comment "PC SMBus host controller drivers" depends on PCI +config PCH_I2C + tristate "PCH I2C" + depends on PCI + help + This driver is for PCH I2C of Topcliff which is an IOH for x86 + embedded processor. + This driver can access PCH I2C bus device. + config I2C_ALI1535 tristate "ALI 1535" depends on PCI
drivers/i2c/busses/Makefile +3 -0
@@ -78,3 +78,6 @@ obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG endif + +obj-$(CONFIG_PCH_I2C) += pch_i2c.o +pch_i2c-objs := i2c-pch.o
drivers/i2c/busses/i2c-pch.c new file +1390 -0
1,390 lines not on this page · raw message
drivers/i2c/busses/i2c-pch.h new file +147 -0
147 lines not on this page · raw message
drivers/i2c/i2c-dev.c +28 -0
@@ -36,6 +36,7 @@#include <linux/i2c-dev.h> #include <linux/jiffies.h> #include <linux/uaccess.h> +#include "busses/i2c-pch.h" static struct i2c_driver i2cdev_driver;
@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ; +if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);
@@ -372,6 +378,12 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)struct i2c_client *client = file->private_data;unsigned long funcs; +unsigned long pch_mode; +int ret; + +struct i2c_msg msg; +unsigned char msgbuf[1 ]; +dev_dbg (&client->adapter->dev,"ioctl, cmd=0x%02x, arg=0x%02lx\n" , cmd, arg);
@@ -427,6 +439,22 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)*/ client->adapter->timeout =msecs_to_jiffies (arg *10 );break ; +case I2C_MODE_SEL : + pch_mode = arg; + +if (pch_mode <=4 ) { + msgbuf[0 ] = pch_mode; + msg.buf = msgbuf; + msg.len =1 ; + msg.flags = (pch_mode <=1 ) ? \ + (PCH_BUFFER_MODE_ENABLE ) : \ + (PCH_EEPROM_SW_RST_MODE_ENABLE ); + ret =i2c_transfer (client->adapter, &msg,1 ); + }else { +printk (KERN_ERR "I2C mode sel:Invalid mode\n" ); + ret = -EINVAL ; + } +return ret;default :/* NOTE: returning a fault code here could cause trouble * in buggy userspace code. Some old kernel bugs returned
Signature · 1 line
1.6.0.6
Arnd Bergmann
maintainerRe: [PATCH] I2C driver of Topcliff PCH
Quoted 7 lines · On Thursday 15 July 2010 09:42:36 Masayuki Ohtak wrote:
I2C driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Topcliff PCH has I2C I/F. Using this I/F, it is able to access system devices connected to I2C.
Looks ok in general. Some minor comments follow:
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/** +* pch_wait_for_bus_idle() - check the status of bus. +* @adap: Pointer to struct i2c_algo_pch_data. +* @timeout: waiting time counter (us). +*/ +static s32 pch_wait_for_bus_idle (struct i2c_algo_pch_data *adap, +s32 timeout) +{ +u32 reg_value; +void __iomem *p = adap->pch_base_address;
drivers/i2c/busses/i2c-pch.c line 137
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ +/* get the status of bus busy */ + reg_value = (ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ); + +while ((timeout !=0 ) && (reg_value !=0 )) { +msleep (1 );/* wait for 100 ms */ + reg_value =ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ; + + timeout--; + }
If you want to wait for a maximum amount of time, a loop with msleep(1) may end up waiting more than twice as long as you want, because each msleep typically returns one milisecond too late.
Better use something like:
time_t timeout = ktime_add_ns(ktime_get(), MAX_NANOSECONDS);
do {
if (ioread32(p + PCH_I2CSR) & I2CMBB_BIT) == 0)
break;
msleep(1);
} while (ktime_lt(ktime_get(), timeout));Quoted 24 lines
drivers/i2c/busses/i2c-pch.c new file +24
-0+/** +* pch_wait_for_xfer_complete() - initiates a wait for the tx complete event +* @adap: Pointer to struct i2c_algo_pch_data. +*/ +static s32 pch_wait_for_xfer_complete (struct i2c_algo_pch_data *adap) +{ +u32 temp_flag; +s32 ret; + ret =wait_event_interruptible_timeout (pch_event, + (adap->pch_event_flag !=0 ),msecs_to_jiffies (50 )); + +dev_dbg (adap->pch_adapter.dev.parent, +"%s adap->pch_event_flag = %x" , __func__, adap->pch_event_flag); + temp_flag = adap->pch_event_flag; + adap->pch_event_flag =0 ; + +if (ret ==0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s : Timeout\n" , __func__); + }else if (ret <0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Interrupted by other signal\n" , __func__); + ret = -ERESTARTSYS ; + }else if ((temp_flag &I2C_ERROR_MASK ) ==0 ) {
drivers/i2c/busses/i2c-pch.c line 202
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ ret =0 ; + }else { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Error in transfer\n" , __func__); + } + +dev_err (adap->pch_adapter.dev.parent,"%s returns %d\n" , __func__, ret); + +return ret; +}
The control flow is much more complex than it needs to be here. If you want to handle different kinds of error conditions, best use goto. Also, it's very unusual to return positive values on errors and to print dev_err messages on success.
int ret;
ret = wait_event_interruptible_timeout(...);
if (ret < 0)
goto out;
if (ret == 0) {
ret = -ETIMEOUT;
goto out;
}
ret = 0;
if (adap->pch_event_flag & I2C_ERROR_MASK) {
ret = -EIO;
dev_err(adap->pch_adapter.dev.parent, "error bits set: %lx\n", adap->pch_event_flag);
}out:
return ret;
Quoted 11 lines
drivers/i2c/busses/i2c-pch.c new file +11
-0+/** +* pch_handler() - interrupt handler for the PCH I2C controller +* @irq: irq number. +* @pData: cookie passed back to the handler function. +*/ +static irqreturn_t pch_handler (int irq,void *pData) +{ +s32 ret; +u32 i; + +struct adapter_info *adap_info = (struct adapter_info *)pData;
drivers/i2c/busses/i2c-pch.c line 547
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/* invoke the call back */ + +if (pch_cbr !=NULL ) { +for (i =0 , ret =0 ; i <PCH_MAX_CHN ; i++) + ret |= (pch_cbr) (&adap_info->pch_data[i]); + }else { +dev_err (adap_info->pch_data[0 ].pch_adapter.dev.parent, +"%s Call back pointer null ..." , __func__); +return IRQ_NONE ; + }
Here you are multiplexing the interrupt yourself. If you don't always use all the available channels, it may be better to register the pch_cbr handler separately for each of the channels that are actually used, so you don't have to invoke the callback for all of them all the time.
Quoted 20 lines
drivers/i2c/busses/i2c-pch.c new file +20
-0+for (i =0 ; i <PCH_MAX_CHN ; i++) { + adap_info->pch_data[i].p_adapter_info = adap_info; + + adap_info->pch_data[i].pch_adapter.owner =THIS_MODULE ; + adap_info->pch_data[i].pch_adapter.class =I2C_CLASS_HWMON ; +strcpy (adap_info->pch_data[i].pch_adapter.name,"pch_i2c" ); + adap_info->pch_data[i].pch_adapter.algo = &pch_algorithm; + adap_info->pch_data[i].pch_adapter.algo_data = + &adap_info->pch_data[i]; + +/* (i * 0x80) + base_addr; */ + adap_info->pch_data[i].pch_base_address = base_addr; + + adap_info->pch_data[i].pch_adapter.dev.parent = &pdev->dev; + + ret =i2c_add_adapter (&(adap_info->pch_data[i].pch_adapter)); + +if (ret) { +dev_err (&pdev->dev,"i2c_add_adapter FAILED" ); + goto err_i2c_add_adapter;
drivers/i2c/busses/i2c-pch.c line 1210
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ } + +dev_dbg (&pdev->dev, +"i2c_add_adapter returns %d for channel-%d\n" , ret, i); +pch_init (&adap_info->pch_data[i]); +dev_dbg (&pdev->dev,"pch_init invoked successfully\n" ); + } + + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);
Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 11 lines
drivers/i2c/i2c-dev.c +5
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ; +if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);
A read function should not do copy_from_user, only copy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.
Arnd
Re: [PATCH] I2C driver of Topcliff PCH
Hi Arnd,
Thank you for you comments.
I will modify our i2c patch by tomorrow.
Thanks, Ohtake
----- Original Message -----
From: "Arnd Bergmann" <[email protected]>
To: "Masayuki Ohtak" <[email protected]>
Cc: "Jean Delvare (PC drivers, core)" <[email protected]>; "Ben Dooks (embedded platforms)" <[email protected]>; <[email protected]>; "LKML" <[email protected]>; <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>
Sent: Friday, July 16, 2010 4:35 AM
Subject: Re: [PATCH] I2C driver of Topcliff PCH
Quoted 188 lines · On Thursday 15 July 2010 09:42:36 Masayuki Ohtak wrote:
Quoted 7 lines
I2C driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Topcliff PCH has I2C I/F. Using this I/F, it is able to access system devices connected to I2C.
Looks ok in general. Some minor comments follow:
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/** +* pch_wait_for_bus_idle() - check the status of bus. +* @adap: Pointer to struct i2c_algo_pch_data. +* @timeout: waiting time counter (us). +*/ +static s32 pch_wait_for_bus_idle (struct i2c_algo_pch_data *adap, +s32 timeout) +{ +u32 reg_value; +void __iomem *p = adap->pch_base_address;drivers/i2c/busses/i2c-pch.c line 137
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ +/* get the status of bus busy */ + reg_value = (ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ); + +while ((timeout !=0 ) && (reg_value !=0 )) { +msleep (1 );/* wait for 100 ms */ + reg_value =ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ; + + timeout--; + }If you want to wait for a maximum amount of time, a loop with msleep(1) may end up waiting more than twice as long as you want, because each msleep typically returns one milisecond too late.
Better use something like:
time_ttimeout =ktime_add_ns(ktime_get(), MAX_NANOSECONDS);do {
if (ioread32(p + PCH_I2CSR)&I2CMBB_BIT) == 0)
break;
msleep(1);
} while (ktime_lt(ktime_get(), timeout));Quoted 24 lines
drivers/i2c/busses/i2c-pch.c new file +24
-0+/** +* pch_wait_for_xfer_complete() - initiates a wait for the tx complete event +* @adap: Pointer to struct i2c_algo_pch_data. +*/ +static s32 pch_wait_for_xfer_complete (struct i2c_algo_pch_data *adap) +{ +u32 temp_flag; +s32 ret; + ret =wait_event_interruptible_timeout (pch_event, + (adap->pch_event_flag !=0 ),msecs_to_jiffies (50 )); + +dev_dbg (adap->pch_adapter.dev.parent, +"%s adap->pch_event_flag = %x" , __func__, adap->pch_event_flag); + temp_flag = adap->pch_event_flag; + adap->pch_event_flag =0 ; + +if (ret ==0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s : Timeout\n" , __func__); + }else if (ret <0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Interrupted by other signal\n" , __func__); + ret = -ERESTARTSYS ; + }else if ((temp_flag &I2C_ERROR_MASK ) ==0 ) {drivers/i2c/busses/i2c-pch.c line 202
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ ret =0 ; + }else { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Error in transfer\n" , __func__); + } + +dev_err (adap->pch_adapter.dev.parent,"%s returns %d\n" , __func__, ret); + +return ret; +}The control flow is much more complex than it needs to be here. If you want to handle different kinds of error conditions, best use goto. Also, it's very unusual to return positive values on errors and to print
dev_errmessages on success.int ret;
ret =wait_event_interruptible_timeout(...);
if (ret < 0)
goto out;if (ret == 0) {
ret =-ETIMEOUT;
goto out;
}ret = 0;
if (adap->pch_event_flag&I2C_ERROR_MASK) {
ret =-EIO;dev_err(adap->pch_adapter.dev.parent, "error bits set: %lx\n", adap->pch_event_flag); }out:
return ret;Quoted 11 lines
drivers/i2c/busses/i2c-pch.c new file +11
-0+/** +* pch_handler() - interrupt handler for the PCH I2C controller +* @irq: irq number. +* @pData: cookie passed back to the handler function. +*/ +static irqreturn_t pch_handler (int irq,void *pData) +{ +s32 ret; +u32 i; + +struct adapter_info *adap_info = (struct adapter_info *)pData;drivers/i2c/busses/i2c-pch.c line 547
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/* invoke the call back */ + +if (pch_cbr !=NULL ) { +for (i =0 , ret =0 ; i <PCH_MAX_CHN ; i++) + ret |= (pch_cbr) (&adap_info->pch_data[i]); + }else { +dev_err (adap_info->pch_data[0 ].pch_adapter.dev.parent, +"%s Call back pointer null ..." , __func__); +return IRQ_NONE ; + }Here you are multiplexing the interrupt yourself. If you don't always use all the available channels, it may be better to register the
pch_cbrhandler separately for each of the channels that are actually used, so you don't have to invoke the callback for all of them all the time.Quoted 20 lines
+ for (i = 0; i <
PCH_MAX_CHN; i++) {
+ adap_info->pch_data[i].p_adapter_info =adap_info;drivers/i2c/busses/i2c-pch.c new file +18
-0+ + adap_info->pch_data[i].pch_adapter.owner =THIS_MODULE ; + adap_info->pch_data[i].pch_adapter.class =I2C_CLASS_HWMON ; +strcpy (adap_info->pch_data[i].pch_adapter.name,"pch_i2c" ); + adap_info->pch_data[i].pch_adapter.algo = &pch_algorithm; + adap_info->pch_data[i].pch_adapter.algo_data = + &adap_info->pch_data[i]; + +/* (i * 0x80) + base_addr; */ + adap_info->pch_data[i].pch_base_address = base_addr; + + adap_info->pch_data[i].pch_adapter.dev.parent = &pdev->dev; + + ret =i2c_add_adapter (&(adap_info->pch_data[i].pch_adapter)); + +if (ret) { +dev_err (&pdev->dev,"i2c_add_adapter FAILED" ); + goto err_i2c_add_adapter;drivers/i2c/busses/i2c-pch.c line 1210
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ } + +dev_dbg (&pdev->dev, +"i2c_add_adapter returns %d for channel-%d\n" , ret, i); +pch_init (&adap_info->pch_data[i]); +dev_dbg (&pdev->dev,"pch_init invoked successfully\n" ); + } + + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 11 lines
drivers/i2c/i2c-dev.c +5
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ; +if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);A read function should not do
copy_from_user, onlycopy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.Arnd
Re: [PATCH] I2C driver of Topcliff PCH
In reply to Arnd BergmannHi Arnd
Quoted 44 lines
Quoted 11 lines
+ struct
adapter_info*adap_info= (structadapter_info*)pData;
+ /* invoke the call back */
+
+ if (pch_cbr!= NULL) {
+ for (i = 0, ret = 0; i <PCH_MAX_CHN; i++)
+ ret |= (pch_cbr) (&adap_info->pch_data[i]);
+ } else {
+ dev_err(adap_info->pch_data[0].pch_adapter.dev.parent,
+ "%s Call back pointer null ...",__func__);
+ returnIRQ_NONE;
+ }Here you are multiplexing the interrupt yourself. If you don't always use all the available channels, it may be better to register the
pch_cbrhandler separately for each of the channels that are actually used, so you don't have to invoke the callback for all of them all the time.Quoted 26 lines
+ for (i = 0; i <
PCH_MAX_CHN; i++) {
+ adap_info->pch_data[i].p_adapter_info =adap_info;drivers/i2c/busses/i2c-pch.c new file +24
-0+ + adap_info->pch_data[i].pch_adapter.owner =THIS_MODULE ; + adap_info->pch_data[i].pch_adapter.class =I2C_CLASS_HWMON ; +strcpy (adap_info->pch_data[i].pch_adapter.name,"pch_i2c" ); + adap_info->pch_data[i].pch_adapter.algo = &pch_algorithm; + adap_info->pch_data[i].pch_adapter.algo_data = + &adap_info->pch_data[i]; + +/* (i * 0x80) + base_addr; */ + adap_info->pch_data[i].pch_base_address = base_addr; + + adap_info->pch_data[i].pch_adapter.dev.parent = &pdev->dev; + + ret =i2c_add_adapter (&(adap_info->pch_data[i].pch_adapter)); + +if (ret) { +dev_err (&pdev->dev,"i2c_add_adapter FAILED" ); + goto err_i2c_add_adapter; + } + +dev_dbg (&pdev->dev, +"i2c_add_adapter returns %d for channel-%d\n" , ret, i); +pch_init (&adap_info->pch_data[i]); +dev_dbg (&pdev->dev,"pch_init invoked successfully\n" );
Quoted 8 lines
drivers/i2c/busses/i2c-pch.c line 1210
Quoted 4 lines
+ }
drivers/i2c/busses/i2c-pch.c new file +3
-0+ + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
With I2c multi-cahnnel IOH, IRQ number is in common. Thus, I think our PCH I2C driver can't be implemented like above.
Thanks, Ohtake.
----- Original Message -----
From: "Arnd Bergmann" <[email protected]>
To: "Masayuki Ohtak" <masa-korg-ECg8zkTtlr0C6LszWs/[email protected]>
Cc: "Jean Delvare (PC drivers, core)" <[email protected]>; "Ben Dooks (embedded platforms)" <[email protected]>; <[email protected]>; "LKML" <[email protected]>; <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>
Sent: Friday, July 16, 2010 4:35 AM
Subject: Re: [PATCH] I2C driver of Topcliff PCH
Quoted 188 lines · On Thursday 15 July 2010 09:42:36 Masayuki Ohtak wrote:
Quoted 7 lines
I2C driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Topcliff PCH has I2C I/F. Using this I/F, it is able to access system devices connected to I2C.
Looks ok in general. Some minor comments follow:
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/** +* pch_wait_for_bus_idle() - check the status of bus. +* @adap: Pointer to struct i2c_algo_pch_data. +* @timeout: waiting time counter (us). +*/ +static s32 pch_wait_for_bus_idle (struct i2c_algo_pch_data *adap, +s32 timeout) +{ +u32 reg_value; +void __iomem *p = adap->pch_base_address;drivers/i2c/busses/i2c-pch.c line 137
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ +/* get the status of bus busy */ + reg_value = (ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ); + +while ((timeout !=0 ) && (reg_value !=0 )) { +msleep (1 );/* wait for 100 ms */ + reg_value =ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ; + + timeout--; + }If you want to wait for a maximum amount of time, a loop with msleep(1) may end up waiting more than twice as long as you want, because each msleep typically returns one milisecond too late.
Better use something like:
time_ttimeout =ktime_add_ns(ktime_get(), MAX_NANOSECONDS);do {
if (ioread32(p + PCH_I2CSR)&I2CMBB_BIT) == 0)
break;
msleep(1);
} while (ktime_lt(ktime_get(), timeout));Quoted 24 lines
drivers/i2c/busses/i2c-pch.c new file +24
-0+/** +* pch_wait_for_xfer_complete() - initiates a wait for the tx complete event +* @adap: Pointer to struct i2c_algo_pch_data. +*/ +static s32 pch_wait_for_xfer_complete (struct i2c_algo_pch_data *adap) +{ +u32 temp_flag; +s32 ret; + ret =wait_event_interruptible_timeout (pch_event, + (adap->pch_event_flag !=0 ),msecs_to_jiffies (50 )); + +dev_dbg (adap->pch_adapter.dev.parent, +"%s adap->pch_event_flag = %x" , __func__, adap->pch_event_flag); + temp_flag = adap->pch_event_flag; + adap->pch_event_flag =0 ; + +if (ret ==0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s : Timeout\n" , __func__); + }else if (ret <0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Interrupted by other signal\n" , __func__); + ret = -ERESTARTSYS ; + }else if ((temp_flag &I2C_ERROR_MASK ) ==0 ) {drivers/i2c/busses/i2c-pch.c line 202
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ ret =0 ; + }else { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Error in transfer\n" , __func__); + } + +dev_err (adap->pch_adapter.dev.parent,"%s returns %d\n" , __func__, ret); + +return ret; +}The control flow is much more complex than it needs to be here. If you want to handle different kinds of error conditions, best use goto. Also, it's very unusual to return positive values on errors and to print
dev_errmessages on success.int ret;
ret =wait_event_interruptible_timeout(...);
if (ret < 0)
goto out;if (ret == 0) {
ret =-ETIMEOUT;
goto out;
}ret = 0;
if (adap->pch_event_flag&I2C_ERROR_MASK) {
ret =-EIO;dev_err(adap->pch_adapter.dev.parent, "error bits set: %lx\n", adap->pch_event_flag); }out:
return ret;Quoted 11 lines
drivers/i2c/busses/i2c-pch.c new file +11
-0+/** +* pch_handler() - interrupt handler for the PCH I2C controller +* @irq: irq number. +* @pData: cookie passed back to the handler function. +*/ +static irqreturn_t pch_handler (int irq,void *pData) +{ +s32 ret; +u32 i; + +struct adapter_info *adap_info = (struct adapter_info *)pData;drivers/i2c/busses/i2c-pch.c line 547
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/* invoke the call back */ + +if (pch_cbr !=NULL ) { +for (i =0 , ret =0 ; i <PCH_MAX_CHN ; i++) + ret |= (pch_cbr) (&adap_info->pch_data[i]); + }else { +dev_err (adap_info->pch_data[0 ].pch_adapter.dev.parent, +"%s Call back pointer null ..." , __func__); +return IRQ_NONE ; + }Here you are multiplexing the interrupt yourself. If you don't always use all the available channels, it may be better to register the
pch_cbrhandler separately for each of the channels that are actually used, so you don't have to invoke the callback for all of them all the time.Quoted 20 lines
+ for (i = 0; i <
PCH_MAX_CHN; i++) {
+ adap_info->pch_data[i].p_adapter_info =adap_info;drivers/i2c/busses/i2c-pch.c new file +18
-0+ + adap_info->pch_data[i].pch_adapter.owner =THIS_MODULE ; + adap_info->pch_data[i].pch_adapter.class =I2C_CLASS_HWMON ; +strcpy (adap_info->pch_data[i].pch_adapter.name,"pch_i2c" ); + adap_info->pch_data[i].pch_adapter.algo = &pch_algorithm; + adap_info->pch_data[i].pch_adapter.algo_data = + &adap_info->pch_data[i]; + +/* (i * 0x80) + base_addr; */ + adap_info->pch_data[i].pch_base_address = base_addr; + + adap_info->pch_data[i].pch_adapter.dev.parent = &pdev->dev; + + ret =i2c_add_adapter (&(adap_info->pch_data[i].pch_adapter)); + +if (ret) { +dev_err (&pdev->dev,"i2c_add_adapter FAILED" ); + goto err_i2c_add_adapter;drivers/i2c/busses/i2c-pch.c line 1210
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ } + +dev_dbg (&pdev->dev, +"i2c_add_adapter returns %d for channel-%d\n" , ret, i); +pch_init (&adap_info->pch_data[i]); +dev_dbg (&pdev->dev,"pch_init invoked successfully\n" ); + } + + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 11 lines
drivers/i2c/i2c-dev.c +5
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ; +if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);A read function should not do
copy_from_user, onlycopy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.Arnd
Arnd Bergmann
maintainerRe: [PATCH] I2C driver of Topcliff PCH
Quoted 14 lines · Masayuki Ohtake
Quoted 5 lines
Quoted 5 lines
+
+ dev_dbg(&pdev->dev,
+ "i2c_add_adapterreturns %d for channel-%d\n", ret, i);
+pch_init(&adap_info->pch_data[i]);
+dev_dbg(&pdev->dev, "pch_init invoked successfully\n");Quoted 8 lines
drivers/i2c/busses/i2c-pch.c line 1210
Quoted 4 lines
+ }
drivers/i2c/busses/i2c-pch.c new file +3
-0+ + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
Quoted 2 lines
With I2c multi-cahnnel IOH, IRQ number is in common. Thus, I think our PCH I2C driver can't be implemented like above.
If you pass IRQF_SHARED, you can register any number of handlers for the same IRQ number using different dev pointers.
Arnd
Re: [PATCH] I2C driver of Topcliff PCH
Hi Arnd,
Quoted 2 lines
If you pass
IRQF_SHARED, you can register any number of handlers for the same IRQ number using different dev pointers.
I will modify like above.
Thanks, Ohtake.
----- Original Message -----
From: "Arnd Bergmann" <[email protected]>
To: "Masayuki Ohtake" <masa-korg-ECg8zkTtlr0C6LszWs/[email protected]>
Cc: "Jean Delvare (PC drivers, core)" <[email protected]>; "Ben Dooks (embedded platforms)" <[email protected]>; <[email protected]>; "LKML" <[email protected]>; <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>
Sent: Tuesday, July 20, 2010 6:27 PM
Subject: Re: [PATCH] I2C driver of Topcliff PCH
Quoted 23 lines · Masayuki Ohtake
Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
+
+ dev_dbg(&pdev->dev,
+ "i2c_add_adapterreturns %d for channel-%d\n", ret, i);
+pch_init(&adap_info->pch_data[i]);
+dev_dbg(&pdev->dev, "pch_init invoked successfully\n");Quoted 8 lines
drivers/i2c/busses/i2c-pch.c line 1210
Quoted 4 lines
+ }
drivers/i2c/busses/i2c-pch.c new file +3
-0+ + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
Quoted 2 lines
With I2c multi-cahnnel IOH, IRQ number is in common. Thus, I think our PCH I2C driver can't be implemented like above.
If you pass
IRQF_SHARED, you can register any number of handlers for the same IRQ number using different dev pointers.Arnd
Re: [PATCH] I2C driver of Topcliff PCH
In reply to Arnd BergmannHi Arnd,
Quoted 4 lines
Quoted 4 lines
drivers/i2c/i2c-dev.c +0
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ;
Quoted 12 lines
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 7 lines
drivers/i2c/i2c-dev.c +5
-0+if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);A read function should not do
copy_from_user, onlycopy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.
Our I2C HW has special mode.
To control the mode, our i2c driver has copy_from_user.
Thanks, Ohtake.
----- Original Message -----
From: "Arnd Bergmann" <[email protected]>
To: "Masayuki Ohtak" <masa-korg-ECg8zkTtlr0C6LszWs/[email protected]>
Cc: "Jean Delvare (PC drivers, core)" <[email protected]>; "Ben Dooks (embedded platforms)" <[email protected]>; <[email protected]>; "LKML" <[email protected]>; <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; <[email protected]>
Sent: Friday, July 16, 2010 4:35 AM
Subject: Re: [PATCH] I2C driver of Topcliff PCH
Quoted 188 lines · On Thursday 15 July 2010 09:42:36 Masayuki Ohtak wrote:
Quoted 7 lines
I2C driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Topcliff PCH has I2C I/F. Using this I/F, it is able to access system devices connected to I2C.
Looks ok in general. Some minor comments follow:
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/** +* pch_wait_for_bus_idle() - check the status of bus. +* @adap: Pointer to struct i2c_algo_pch_data. +* @timeout: waiting time counter (us). +*/ +static s32 pch_wait_for_bus_idle (struct i2c_algo_pch_data *adap, +s32 timeout) +{ +u32 reg_value; +void __iomem *p = adap->pch_base_address;drivers/i2c/busses/i2c-pch.c line 137
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ +/* get the status of bus busy */ + reg_value = (ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ); + +while ((timeout !=0 ) && (reg_value !=0 )) { +msleep (1 );/* wait for 100 ms */ + reg_value =ioread32 (p +PCH_I2CSR ) &I2CMBB_BIT ; + + timeout--; + }If you want to wait for a maximum amount of time, a loop with msleep(1) may end up waiting more than twice as long as you want, because each msleep typically returns one milisecond too late.
Better use something like:
time_ttimeout =ktime_add_ns(ktime_get(), MAX_NANOSECONDS);do {
if (ioread32(p + PCH_I2CSR)&I2CMBB_BIT) == 0)
break;
msleep(1);
} while (ktime_lt(ktime_get(), timeout));Quoted 24 lines
drivers/i2c/busses/i2c-pch.c new file +24
-0+/** +* pch_wait_for_xfer_complete() - initiates a wait for the tx complete event +* @adap: Pointer to struct i2c_algo_pch_data. +*/ +static s32 pch_wait_for_xfer_complete (struct i2c_algo_pch_data *adap) +{ +u32 temp_flag; +s32 ret; + ret =wait_event_interruptible_timeout (pch_event, + (adap->pch_event_flag !=0 ),msecs_to_jiffies (50 )); + +dev_dbg (adap->pch_adapter.dev.parent, +"%s adap->pch_event_flag = %x" , __func__, adap->pch_event_flag); + temp_flag = adap->pch_event_flag; + adap->pch_event_flag =0 ; + +if (ret ==0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s : Timeout\n" , __func__); + }else if (ret <0 ) { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Interrupted by other signal\n" , __func__); + ret = -ERESTARTSYS ; + }else if ((temp_flag &I2C_ERROR_MASK ) ==0 ) {drivers/i2c/busses/i2c-pch.c line 202
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ ret =0 ; + }else { +dev_err (adap->pch_adapter.dev.parent, +"%s failed : Error in transfer\n" , __func__); + } + +dev_err (adap->pch_adapter.dev.parent,"%s returns %d\n" , __func__, ret); + +return ret; +}The control flow is much more complex than it needs to be here. If you want to handle different kinds of error conditions, best use goto. Also, it's very unusual to return positive values on errors and to print
dev_errmessages on success.int ret;
ret =wait_event_interruptible_timeout(...);
if (ret < 0)
goto out;if (ret == 0) {
ret =-ETIMEOUT;
goto out;
}ret = 0;
if (adap->pch_event_flag&I2C_ERROR_MASK) {
ret =-EIO;dev_err(adap->pch_adapter.dev.parent, "error bits set: %lx\n", adap->pch_event_flag); }out:
return ret;Quoted 11 lines
drivers/i2c/busses/i2c-pch.c new file +11
-0+/** +* pch_handler() - interrupt handler for the PCH I2C controller +* @irq: irq number. +* @pData: cookie passed back to the handler function. +*/ +static irqreturn_t pch_handler (int irq,void *pData) +{ +s32 ret; +u32 i; + +struct adapter_info *adap_info = (struct adapter_info *)pData;drivers/i2c/busses/i2c-pch.c line 547
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+/* invoke the call back */ + +if (pch_cbr !=NULL ) { +for (i =0 , ret =0 ; i <PCH_MAX_CHN ; i++) + ret |= (pch_cbr) (&adap_info->pch_data[i]); + }else { +dev_err (adap_info->pch_data[0 ].pch_adapter.dev.parent, +"%s Call back pointer null ..." , __func__); +return IRQ_NONE ; + }Here you are multiplexing the interrupt yourself. If you don't always use all the available channels, it may be better to register the
pch_cbrhandler separately for each of the channels that are actually used, so you don't have to invoke the callback for all of them all the time.Quoted 20 lines
+ for (i = 0; i <
PCH_MAX_CHN; i++) {
+ adap_info->pch_data[i].p_adapter_info =adap_info;drivers/i2c/busses/i2c-pch.c new file +18
-0+ + adap_info->pch_data[i].pch_adapter.owner =THIS_MODULE ; + adap_info->pch_data[i].pch_adapter.class =I2C_CLASS_HWMON ; +strcpy (adap_info->pch_data[i].pch_adapter.name,"pch_i2c" ); + adap_info->pch_data[i].pch_adapter.algo = &pch_algorithm; + adap_info->pch_data[i].pch_adapter.algo_data = + &adap_info->pch_data[i]; + +/* (i * 0x80) + base_addr; */ + adap_info->pch_data[i].pch_base_address = base_addr; + + adap_info->pch_data[i].pch_adapter.dev.parent = &pdev->dev; + + ret =i2c_add_adapter (&(adap_info->pch_data[i].pch_adapter)); + +if (ret) { +dev_err (&pdev->dev,"i2c_add_adapter FAILED" ); + goto err_i2c_add_adapter;drivers/i2c/busses/i2c-pch.c line 1210
Quoted 10 lines
drivers/i2c/busses/i2c-pch.c new file +10
-0+ } + +dev_dbg (&pdev->dev, +"i2c_add_adapter returns %d for channel-%d\n" , ret, i); +pch_init (&adap_info->pch_data[i]); +dev_dbg (&pdev->dev,"pch_init invoked successfully\n" ); + } + + ret =request_irq (pdev->irq, &pch_handler,IRQF_SHARED , +MODULE_NAME , adap_info);Similarly, you would create a new channel data structure for each channel here and register it separately, and then request the interrupt with that data structure as the info.
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 11 lines
drivers/i2c/i2c-dev.c +5
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ; +if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);A read function should not do
copy_from_user, onlycopy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.Arnd
Arnd Bergmann
maintainerRe: [PATCH] I2C driver of Topcliff PCH
Quoted 17 lines · Masayuki Ohtake
Quoted 4 lines
Quoted 4 lines
drivers/i2c/i2c-dev.c +0
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ;Quoted 12 lines
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 7 lines
drivers/i2c/i2c-dev.c +5
-0+if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);A read function should not do
copy_from_user, onlycopy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.
Quoted 2 lines
Our I2C HW has special mode.
To control the mode, our i2c driver hascopy_from_user.
That is a highly unusual interface and I would definitely not recommend doing this. Please use an ioctl operation for anything that has both input and output data.
Arnd
Re: [PATCH] I2C driver of Topcliff PCH
Hi Arnd,
Quoted 3 lines
That is a highly unusual interface and I would definitely not recommend doing this. Please use an ioctl operation for anything that has both input and output data.
I will delete the special interface from our i2c driver.
Thanks, Ohtake
----- Original Message -----
From: "Arnd Bergmann" <[email protected]>
To: "Masayuki Ohtake" <masa-korg-ECg8zkTtlr0C6LszWs/[email protected]>
Cc: <[email protected]>; <[email protected]>; "Wang, Yong Y" <[email protected]>; <[email protected]>; "LKML" <[email protected]>; <[email protected]>; "Ben Dooks (embedded platforms)" <[email protected]>; "Jean Delvare (PC drivers, core)" <[email protected]>
Sent: Tuesday, July 20, 2010 6:29 PM
Subject: Re: [PATCH] I2C driver of Topcliff PCH
Quoted 27 lines · Masayuki Ohtake
Quoted 17 lines
Quoted 4 lines
Quoted 4 lines
drivers/i2c/i2c-dev.c +0
-0@@ -147,6 +148,11 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,if (tmp ==NULL )return -ENOMEM ;Quoted 12 lines
drivers/i2c/i2c-dev.c static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, · line 157
Quoted 7 lines
drivers/i2c/i2c-dev.c +5
-0+if (copy_from_user (tmp, buf, count)) { +kfree (tmp); +return -EFAULT ; + } +pr_debug ("i2c-dev: i2c-%d reading %zu bytes.\n" ,iminor (file->f_path.dentry->d_inode), count);A read function should not do
copy_from_user, onlycopy_to_user. If you are worried about returning invalid data from kernel space, better use kzalloc instead of kmalloc to get the buffer.Quoted 2 lines
Our I2C HW has special mode.
To control the mode, our i2c driver hascopy_from_user.That is a highly unusual interface and I would definitely not recommend doing this. Please use an ioctl operation for anything that has both input and output data.
Arnd
PATCH 1/1 I2C driver of Topcliff PCH
In reply to Masayuki OhtakHi Arnd,
I have modified for your comments.
Please confirm below.
Thanks, Ohtake
---
I2C driver of Topcliff PCH
Topcliff PCH is the platform controller hub that is going to be used in Intel's upcoming general embedded platform. All IO peripherals in Topcliff PCH are actually devices sitting on AMBA bus. Topcliff PCH has I2C I/F. Using this I/F, it is able to access system devices connected to I2C.
--- drivers/i2c/busses/Kconfig | 8 + drivers/i2c/busses/Makefile | 3 + drivers/i2c/busses/i2c-pch.c | 910 ++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-pch.h | 147 +++++++ drivers/i2c/i2c-dev.c | 21 + 5 files changed, 1089 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-pch.c create mode 100644 drivers/i2c/busses/i2c-pch.h
drivers/i2c/busses/Kconfig +8 -0
@@ -7,6 +7,14 @@ menu "I2C Hardware Bus support" comment "PC SMBus host controller drivers" depends on PCI +config PCH_I2C + tristate "PCH I2C" + depends on PCI + help + This driver is for PCH I2C of Topcliff which is an IOH for x86 + embedded processor. + This driver can access PCH I2C bus device. + config I2C_ALI1535 tristate "ALI 1535" depends on PCI
drivers/i2c/busses/Makefile +3 -0
@@ -75,3 +75,6 @@ obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG endif + +obj-$(CONFIG_PCH_I2C) += pch_i2c.o +pch_i2c-objs := i2c-pch.o
drivers/i2c/busses/i2c-pch.c new file +910 -0
910 lines not on this page · raw message
drivers/i2c/busses/i2c-pch.h new file +147 -0
147 lines not on this page · raw message
drivers/i2c/i2c-dev.c +21 -0
@@ -36,6 +36,7 @@#include <linux/i2c-dev.h> #include <linux/jiffies.h> #include <linux/uaccess.h> +#include "busses/i2c-pch.h" static struct i2c_driver i2cdev_driver;
@@ -372,6 +373,12 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)struct i2c_client *client = file->private_data;unsigned long funcs; +unsigned long pch_mode; +int ret; + +struct i2c_msg msg; +unsigned char msgbuf[1 ]; +dev_dbg (&client->adapter->dev,"ioctl, cmd=0x%02x, arg=0x%02lx\n" , cmd, arg);
@@ -427,6 +434,20 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)*/ client->adapter->timeout =msecs_to_jiffies (arg *10 );break ; +case I2C_MODE_SEL : + pch_mode = arg; + +if (pch_mode <=4 ) { + msgbuf[0 ] = pch_mode; + msg.buf = msgbuf; + msg.len =1 ; + msg.flags =0 ; + ret =i2c_transfer (client->adapter, &msg,1 ); + }else { +printk (KERN_ERR "I2C mode sel:Invalid mode\n" ); + ret = -EINVAL ; + } +return ret;default :/* NOTE: returning a fault code here could cause trouble * in buggy userspace code. Some old kernel bugs returned
Signature · 1 line
1.6.0.6