SOURCES: kernel-mpt-fusion.patch (NEW) - v4.00.43.00 - taken from http://do...
baggins
baggins at pld-linux.org
Thu Nov 27 17:10:39 CET 2008
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 <hare at suse.de>
+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 <Sathya.Prakash at lsi.com>
+Signed-off-by: Hannes Reinecke <hare at suse.de>
+
+---
+ 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:DL-MPTFusionLinux at lsi.com)
++ */
++/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
++/*
++ 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>>
More information about the pld-cvs-commit
mailing list