Author: baggins Date: Thu Nov 27 16:10:39 2008 GMT Module: SOURCES Tag: HEAD ---- Log message: - v4.00.43.00 - taken from http://download.opensuse.org/factory/repo/src-oss/suse/src/kernel-source-2.6.27.7-3.1.src.rpm
---- Files affected: SOURCES: kernel-mpt-fusion.patch (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/kernel-mpt-fusion.patch diff -u /dev/null SOURCES/kernel-mpt-fusion.patch:1.1 --- /dev/null Thu Nov 27 17:10:39 2008 +++ SOURCES/kernel-mpt-fusion.patch Thu Nov 27 17:10:33 2008 @@ -0,0 +1,28445 @@ +Subject: Update MPT Fusion driver to v4.00.43.00 +From: Hannes Reinecke <[EMAIL PROTECTED]> +Date: Tue Sep 30 13:38:53 2008 +0200: +Git: a958ec0d1685af04282982f2e53b66c947fc7426 + +References: bnc#425660 + +This patch updates the MPT fusion drivers to v4.00.43.00. + +Signed-off-by: Sathya Prakash <[EMAIL PROTECTED]> +Signed-off-by: Hannes Reinecke <[EMAIL PROTECTED]> + +--- + drivers/message/fusion/Kconfig | 16 + drivers/message/fusion/Makefile | 13 + drivers/message/fusion/csmi/csmisas.c | 5888 ++++++++++++++++++ + drivers/message/fusion/csmi/csmisas.h | 1854 +++++ + drivers/message/fusion/lsi/mpi.h | 7 + drivers/message/fusion/lsi/mpi_cnfg.h | 47 + drivers/message/fusion/lsi/mpi_fc.h | 2 + drivers/message/fusion/lsi/mpi_history.txt | 86 + drivers/message/fusion/lsi/mpi_init.h | 2 + drivers/message/fusion/lsi/mpi_ioc.h | 22 + drivers/message/fusion/lsi/mpi_lan.h | 2 + drivers/message/fusion/lsi/mpi_log_fc.h | 2 + drivers/message/fusion/lsi/mpi_log_sas.h | 31 + drivers/message/fusion/lsi/mpi_raid.h | 11 + drivers/message/fusion/lsi/mpi_sas.h | 18 + drivers/message/fusion/lsi/mpi_targ.h | 2 + drivers/message/fusion/lsi/mpi_tool.h | 2 + drivers/message/fusion/lsi/mpi_type.h | 19 + drivers/message/fusion/mptbase.c | 2700 +++++--- + drivers/message/fusion/mptbase.h | 291 + drivers/message/fusion/mptctl.c | 1020 +-- + drivers/message/fusion/mptctl.h | 5 + drivers/message/fusion/mptdebug.h | 12 + drivers/message/fusion/mptfc.c | 189 + drivers/message/fusion/mptlan.c | 56 + drivers/message/fusion/mptlan.h | 3 + drivers/message/fusion/mptsas.c | 5921 ++++++++++++------- + drivers/message/fusion/mptsas.h | 71 + drivers/message/fusion/mptscsih.c | 2252 +++---- + drivers/message/fusion/mptscsih.h | 13 + drivers/message/fusion/mptspi.c | 265 + drivers/message/fusion/rejected_ioctls/diag_buffer.c | 667 ++ + drivers/message/fusion/rejected_ioctls/diag_buffer.h | 101 + 33 files changed, 16615 insertions(+), 4975 deletions(-) + +--- /dev/null ++++ b/drivers/message/fusion/csmi/csmisas.c +@@ -0,0 +1,5888 @@ ++/* ++ * linux/drivers/message/fusion/csmi/csmisas.c ++ * For use with LSI PCI chip/adapter(s) ++ * running LSI Fusion MPT (Message Passing Technology) firmware. ++ * ++ * Copyright (c) 1999-2008 LSI Corporation ++ * (mailto:[EMAIL PROTECTED]) ++ */ ++/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ ++/* ++ 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. ++ ++ NO WARRANTY ++ THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ solely responsible for determining the appropriateness of using and ++ distributing the Program and assumes all risks associated with its ++ exercise of rights under this Agreement, including but not limited to ++ the risks and costs of program errors, damage to or loss of data, ++ programs or equipment, and unavailability or interruption of operations. ++ ++ DISCLAIMER OF LIABILITY ++ NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ 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 MPT_CSMI_DESCRIPTION "LSI Corporation: Fusion MPT Driver "MPT_LINUX_VERSION_COMMON ++#define csmisas_is_this_sas_cntr(ioc) (ioc->bus_type == SAS) ? 1 : 0 ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++#define __user ++#include <asm/div64.h> ++#endif ++ ++static int csmisas_do_raid(MPT_ADAPTER *ioc, u8 action, u8 PhysDiskNum, u8 VolumeBus, ++ u8 VolumeId, pMpiRaidActionReply_t reply); ++static u8 map_sas_status_to_csmi(u8 mpi_sas_status); ++ ++/** ++ * reverse_byte_order64 ++ * ++ * @data64 ++ * ++ **/ ++static u64 ++reverse_byte_order64(u64 data64) ++{ ++ int i; ++ u64 rc; ++ u8 *inWord = (u8*)&data64, *outWord = (u8*)&rc; ++ ++ for (i = 0 ; i < 8 ; i++) ++ outWord[i] = inWord[7-i]; ++ ++ return rc; ++} ++ ++/** ++ * csmisas_is_sata ++ * ++ * @phys_disk ++ * ++ **/ ++static int ++csmisas_is_sata(RaidPhysDiskPage0_t *phys_disk) ++{ ++ if ((phys_disk->ExtDiskIdentifier[0] == 'A') && ++ (phys_disk->ExtDiskIdentifier[1] == 'T') && ++ (phys_disk->ExtDiskIdentifier[2] == 'A')) ++ return 1; ++ else ++ return 0; ++} ++ ++/** ++ * csmisas_is_end_device ++ * ++ * @attached ++ * ++ **/ ++static inline int ++csmisas_is_end_device(struct mptsas_devinfo * attached) ++{ ++ if ((attached->sas_address) && ++ (attached->device_info & ++ MPI_SAS_DEVICE_INFO_END_DEVICE) && ++ ((attached->device_info & ++ MPI_SAS_DEVICE_INFO_SSP_TARGET) | ++ (attached->device_info & ++ MPI_SAS_DEVICE_INFO_STP_TARGET) | ++ (attached->device_info & ++ MPI_SAS_DEVICE_INFO_SATA_DEVICE))) ++ return 1; ++ else ++ return 0; ++} ++ ++/** ++ * csmisas_is_phys_disk ++ * ++ * returns (1) success (0) fail - not a phys disk ++ **/ ++static int ++csmisas_is_phys_disk(MPT_ADAPTER *ioc, int channel, int id) ++{ ++ struct inactive_raid_component_info *component_info; ++ int i; ++ int rc = 0; ++ ++ if (!ioc->raid_data.pIocPg3) ++ goto out; ++ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { ++ if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && ++ (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { ++ rc = 1; ++ goto out; ++ } ++ } ++ ++ /* ++ * Check inactive list for matching phys disks ++ */ ++ if (list_empty(&ioc->raid_data.inactive_list)) ++ goto out; ++ ++ down(&ioc->raid_data.inactive_list_mutex); ++ list_for_each_entry(component_info, &ioc->raid_data.inactive_list, ++ list) { ++ if ((component_info->d.PhysDiskID == id) && ++ (component_info->d.PhysDiskBus == channel)) ++ rc = 1; ++ } ++ up(&ioc->raid_data.inactive_list_mutex); ++ ++ out: ++ return rc; ++} ++ ++/** ++ * csmisas_raid_id_to_num ++ * ++ * Obtains the phys disk num for given H:C:T nexus ++ * ++ * input (channel/id) ++ * output (phys disk number - used by SCSI_IO_PASSTHRU to access hidden component) ++ * ++ * returns - signed return means failure ++ **/ ++static s8 ++csmisas_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) ++{ ++ struct inactive_raid_component_info *component_info; ++ int i; ++ s8 rc = -ENXIO; ++ ++ if (!ioc->raid_data.pIocPg3) ++ goto out; ++ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { ++ if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && ++ (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { ++ rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; ++ goto out; ++ } ++ } ++ ++ /* ++ * Check inactive list for matching phys disks ++ */ ++ if (list_empty(&ioc->raid_data.inactive_list)) ++ goto out; ++ ++ down(&ioc->raid_data.inactive_list_mutex); ++ list_for_each_entry(component_info, &ioc->raid_data.inactive_list, ++ list) { ++ if ((component_info->d.PhysDiskID == id) && ++ (component_info->d.PhysDiskBus == channel)) ++ rc = component_info->d.PhysDiskNum; ++ } ++ up(&ioc->raid_data.inactive_list_mutex); ++ ++ out: ++ return rc; ++} ++ ++/** ++ * csmisas_get_device_component_by_os ++ * ++ * Obtain device component object by operating system mapping ++ * ++ * @ioc ++ * @channel ++ * @id ++ * ++ **/ ++static struct sas_device_info * ++csmisas_get_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id) ++{ ++ struct sas_device_info *sas_info, *p; ++ ++ sas_info = NULL; ++ ++ down(&ioc->sas_device_info_mutex); ++ list_for_each_entry(p, &ioc->sas_device_info_list, list) { ++ if (p->os.channel == channel && p->os.id == id) { ++ sas_info = p; ++ goto out; ++ } ++ } ++ ++ out: ++ up(&ioc->sas_device_info_mutex); ++ return sas_info; ++} ++ ++/** ++ * csmisas_get_device_component ++ * ++ * Obtain device component object by firmware system mapping ++ * ++ * @ioc ++ * @channel ++ * @id ++ * ++ **/ ++static struct sas_device_info * ++csmisas_get_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id) ++{ ++ struct sas_device_info *sas_info, *p; ++ ++ sas_info = NULL; ++ ++ down(&ioc->sas_device_info_mutex); ++ list_for_each_entry(p, &ioc->sas_device_info_list, list) { ++ if (p->fw.channel == channel && p->fw.id == id) { ++ sas_info = p; ++ goto out; ++ } ++ } ++ ++ out: ++ up(&ioc->sas_device_info_mutex); ++ return sas_info; ++} ++ ++ ++/** ++ * csmisas_get_device_component_by_sas_addr ++ * ++ * Obtain device component object by sas address ++ * ++ * @ioc ++ * @channel ++ * @id ++ * ++ **/ ++static struct sas_device_info * ++csmisas_get_device_component_by_sas_addr(MPT_ADAPTER *ioc, u64 sas_address) ++{ ++ struct sas_device_info *sas_info, *p; ++ ++ sas_info = NULL; ++ ++ down(&ioc->sas_device_info_mutex); ++ list_for_each_entry(p, &ioc->sas_device_info_list, list) { ++ if (p->sas_address == sas_address) { ++ sas_info = p; ++ goto out; ++ } ++ } ++ ++ out: ++ up(&ioc->sas_device_info_mutex); ++ return sas_info; ++} ++ ++/** ++ * csmisas_send_command_wait ++ * ++ * Send mf to firmware ++ * ++ * @ioc ++ * @mf ++ * @timeout - timeout ++ * ++ * Return: 0 for success ++ * non-zero, failure ++ **/ ++static int ++csmisas_send_command_wait(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, unsigned long timeout) ++{ ++ int rc; ++ unsigned long timeleft; ++ ++ timeout = max_t(unsigned long, MPT_IOCTL_DEFAULT_TIMEOUT, timeout); ++ rc = 0; ++ timeleft = 0; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++ ++ INITIALIZE_IOCTL_STATUS(ioc->ioctl_cmds.status) ++ ioc->ioctl_cmds.wait_done = 0; ++ ioc->ioctl_cmds.timer.expires = jiffies + (MPT_JIFFY * timeout); ++ ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_TIMER_ACTIVE; ++ ADD_TIMER(&ioc->ioctl_cmds.timer); ++ mpt_put_msg_frame(mptctl_id, ioc, mf); ++ WAIT_EVENT(mptctl_wait, ioc->ioctl_cmds.wait_done); ++ ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) ++ ++ INITIALIZE_IOCTL_STATUS(ioc->ioctl_cmds.status) ++ ioc->ioctl_cmds.wait_done = 0; ++ mpt_put_msg_frame(mptctl_id, ioc, mf); ++ ++ if ((wait_event_timeout(mptctl_wait, ++ ioc->ioctl_cmds.wait_done == 1, HZ * timeout) <=0) && ++ ioc->ioctl_cmds.wait_done != 1 ) { ++ mptctl_timeout_expired(ioc,mf); ++ mpt_free_msg_frame(ioc, mf); ++ rc = -1; ++ } ++ ++#else ++ ++ SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, ++ mf->u.hdr.MsgContext); ++ INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status) ++ mpt_put_msg_frame(mptctl_id, ioc, mf); ++ timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done, timeout*HZ); ++ if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { ++ rc = -1; ++ printk("%s: failed\n", __FUNCTION__); ++ if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) { ++ mpt_free_msg_frame(ioc, mf); ++ CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status) ++ return rc; ++ } ++ if (!timeleft) ++ mptctl_timeout_expired(ioc, mf); ++ } ++ SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0); ++#endif ++ return rc; ++} ++ ++/** ++ * csmisas_send_handshake_wait ++ * ++ * Handshake a mf to firmware ++ * ++ * @ioc ++ * @mf ++ * @mf_size ++ * @timeout - timeout ++ * ++ * Return: 0 for success ++ * non-zero, failure ++ **/ ++static int ++csmisas_send_handshake_wait(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, unsigned long timeout) ++{ ++ int rc; ++ unsigned long timeleft; ++ ++ timeout = max_t(unsigned long, MPT_IOCTL_DEFAULT_TIMEOUT, timeout); ++ rc = 0; ++ timeleft = 0; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++ ++ INITIALIZE_IOCTL_STATUS(ioc->taskmgmt_cmds.status) ++ ioc->taskmgmt_cmds.timer.expires = jiffies + (MPT_JIFFY*timeout); ++ ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_TIMER_ACTIVE; ++ ioc->taskmgmt_cmds.wait_done = 0; ++ ADD_TIMER(&ioc->taskmgmt_cmds.timer); ++ rc = mpt_send_special_message(mptctl_taskmgmt_id, ioc, ++ sizeof(SCSITaskMgmt_t), (u32*)mf, timeout, CAN_SLEEP); ++ if (rc != 0) ++ return rc; ++ WAIT_EVENT(mptctl_taskmgmt_wait, ioc->taskmgmt_cmds.wait_done); ++ ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) ++ ++ INITIALIZE_IOCTL_STATUS(ioc->taskmgmt_cmds.status) ++ ioc->taskmgmt_cmds.wait_done = 0; ++ rc = mpt_send_special_message(mptctl_taskmgmt_id, ioc, ++ sizeof(SCSITaskMgmt_t), (u32*)mf, timeout, CAN_SLEEP); ++ if (rc != 0) ++ return rc; ++ if ((wait_event_timeout(mptctl_taskmgmt_wait, ++ ioc->taskmgmt_cmds.wait_done == 1, HZ * timeout) <=0) && ++ ioc->taskmgmt_cmds.wait_done != 1 ) { ++ mptctl_timeout_expired(ioc, mf); ++ mpt_free_msg_frame(ioc, mf); ++ rc = -1; ++ } ++ ++#else ++ INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status) ++ mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf); ++ timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ); ++ if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { ++ rc = -1; ++ printk("%s: failed\n", __FUNCTION__); ++ mpt_clear_taskmgmt_in_progress_flag(ioc); ++ if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) { ++ mpt_free_msg_frame(ioc, mf); ++ CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) ++ return rc; ++ } ++ if (!timeleft) ++ mptctl_timeout_expired(ioc, mf); ++ } ++#endif ++ return rc; ++} ++ ++/** ++ * csmisas_get_number_hotspares - returns num hot spares in this ioc ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * ++ * Return: number of hotspares ++ * ++ **/ ++static int ++csmisas_get_number_hotspares(MPT_ADAPTER *ioc) ++{ ++ ConfigPageHeader_t hdr; ++ CONFIGPARMS cfg; ++ IOCPage5_t *buffer = NULL; ++ dma_addr_t dma_handle; ++ int data_sz; ++ int rc; ++ ++ memset(&hdr, 0, sizeof(ConfigPageHeader_t)); ++ memset(&cfg, 0, sizeof(CONFIGPARMS)); ++ ++ rc = 0; ++ data_sz = 0; ++ hdr.PageNumber = 5; ++ hdr.PageType = MPI_CONFIG_PAGETYPE_IOC; ++ cfg.cfghdr.hdr = &hdr; ++ cfg.physAddr = -1; ++ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; ++ cfg.timeout = MPT_IOCTL_DEFAULT_TIMEOUT; ++ ++ if (mpt_config(ioc, &cfg) != 0) ++ goto get_ioc_pg5; ++ ++ if (hdr.PageLength == 0) ++ goto get_ioc_pg5; ++ ++ data_sz = hdr.PageLength * 4; ++ buffer = (IOCPage5_t *) pci_alloc_consistent(ioc->pcidev, ++ data_sz, &dma_handle); ++ if (!buffer) ++ goto get_ioc_pg5; ++ ++ memset((u8 *)buffer, 0, data_sz); ++ cfg.physAddr = dma_handle; ++ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; ++ ++ if (mpt_config(ioc, &cfg) != 0) ++ goto get_ioc_pg5; ++ ++ rc = buffer->NumHotSpares; ++ ++ get_ioc_pg5: ++ ++ if (buffer) ++ pci_free_consistent(ioc->pcidev, data_sz, ++ (u8 *) buffer, dma_handle); ++ ++ return rc; ++} ++ ++ ++/** ++ * csmisas_get_ioc_pg5 - ioc Page 5 hot spares ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @pIocPage5: ioc page 5 ++ * @data_size: expected data size(units=bytes) ++ * ++ * Return: 0 for success ++ * -ENOMEM if no memory available ++ * -EPERM if not allowed due to ISR context ++ * -EAGAIN if no msg frames currently available ++ * -EFAULT for non-successful reply or no reply (timeout) ++ **/ ++static int ++csmisas_get_ioc_pg5(MPT_ADAPTER *ioc, IOCPage5_t *iocPage5, int data_size) ++{ ++ ConfigPageHeader_t hdr; ++ CONFIGPARMS cfg; ++ IOCPage5_t *buffer = NULL; ++ dma_addr_t dma_handle; ++ int data_sz; ++ int rc; ++ ++ memset(&hdr, 0, sizeof(ConfigPageHeader_t)); ++ memset(&cfg, 0, sizeof(CONFIGPARMS)); ++ ++ rc = 0; ++ data_sz = 0; ++ hdr.PageNumber = 5; ++ hdr.PageType = MPI_CONFIG_PAGETYPE_IOC; ++ cfg.cfghdr.hdr = &hdr; ++ cfg.physAddr = -1; ++ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; ++ cfg.timeout = MPT_IOCTL_DEFAULT_TIMEOUT; ++ ++ if ((rc = mpt_config(ioc, &cfg)) != 0) ++ goto get_ioc_pg5; ++ ++ if (hdr.PageLength == 0) { ++ rc = -EFAULT; ++ goto get_ioc_pg5; ++ } ++ ++ data_sz = hdr.PageLength * 4; ++ buffer = (IOCPage5_t *) pci_alloc_consistent(ioc->pcidev, ++ data_sz, &dma_handle); <<Diff was trimmed, longer than 597 lines>> _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
