From patchwork Fri Apr 8 19:02:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: babu moger X-Patchwork-Id: 695401 Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p38J3sV5002675 for ; Fri, 8 Apr 2011 19:04:15 GMT Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p38J1dxN009244; Fri, 8 Apr 2011 15:01:39 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p38J1bcG003121 for ; Fri, 8 Apr 2011 15:01:37 -0400 Received: from mx1.redhat.com (ext-mx11.extmail.prod.ext.phx2.redhat.com [10.5.110.16]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p38J1Wb7011050 for ; Fri, 8 Apr 2011 15:01:32 -0400 Received: from na3sys009aog110.obsmtp.com (na3sys009aog110.obsmtp.com [74.125.149.203]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p38J1SCr012682 for ; Fri, 8 Apr 2011 15:01:28 -0400 Received: from cosedge01.lsi.com ([192.19.220.66]) (using TLSv1) by na3sys009aob110.postini.com ([74.125.148.12]) with SMTP ID DSNKTZ9biI8PD+UaOCVowbh5RsLcRZQjMYn2@postini.com; Fri, 08 Apr 2011 12:01:28 PDT Received: from coscas01.lsi.com (172.21.36.60) by COSEDGE01.lsi.com (192.19.220.66) with Microsoft SMTP Server (TLS) id 8.3.137.0; Fri, 8 Apr 2011 13:00:35 -0600 Received: from cosmail01.lsi.com ([172.21.36.24]) by coscas01.lsi.com ([172.21.36.60]) with mapi; Fri, 8 Apr 2011 13:02:49 -0600 From: "Moger, Babu" To: device-mapper development Date: Fri, 8 Apr 2011 13:02:44 -0600 Thread-Topic: [PATCH 1/1] multipath-tools: Set the rdac TAS bit if it changeable Thread-Index: Acv2H4q0sakGZEvkT6epWvagX+HzHA== Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 X-RedHat-Spam-Score: -2.3 (RCVD_IN_DNSWL_MED) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-Scanned-By: MIMEDefang 2.68 on 10.5.110.16 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id p38J1bcG003121 X-loop: dm-devel@redhat.com Cc: "Krishnasamy, Somasundaram" , "Stankey, Robert" Subject: [dm-devel] [PATCH 1/1] multipath-tools: Set the rdac TAS bit if it changeable X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 08 Apr 2011 19:04:16 +0000 (UTC) This patch sets the rdac TAS bit if it is changeable. This is called only once per lun during the discovery. The Task Aborted Status (TAS) bit in Control Mode Page (Page 0x0A) controls the behavior of aborted tasks. By default, the TAS bit is set to zero. The rdac checker should issue a mode sense page 0x0A to determine the TAS bit value and whether or not the TAS bit is changeable. If the TAS bit is set to 0 and changeable, the rdac checker should issue a mode select page 0x0A to change TAS to 1 and save it. Signed-off-by: Babu Moger Reviewed-by : Yanling Qi Reviewed-by : Somasundaram Krishnasamy --- -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel --- multipath-tools/libmultipath/checkers/rdac.c.orig 2011-04-08 10:08:42.000000000 -0500 +++ multipath-tools/libmultipath/checkers/rdac.c 2011-04-08 10:22:21.000000000 -0500 @@ -12,27 +12,113 @@ #include #include "checkers.h" +#include "debug.h" #include "../libmultipath/sg_include.h" #define INQUIRY_CMDLEN 6 #define INQUIRY_CMD 0x12 +#define MODE_SENSE_CMD 0x5a +#define MODE_SELECT_CMD 0x55 +#define MODE_SEN_SEL_CMDLEN 10 #define SENSE_BUFF_LEN 32 #define SCSI_CHECK_CONDITION 0x2 #define SCSI_COMMAND_TERMINATED 0x22 #define SG_ERR_DRIVER_SENSE 0x08 #define RECOVERED_ERROR 0x01 + +#define CURRENT_PAGE_CODE_VALUES 0 +#define CHANGEABLE_PAGE_CODE_VALUES 1 + #define MSG_RDAC_UP "rdac checker reports path is up" #define MSG_RDAC_DOWN "rdac checker reports path is down" #define MSG_RDAC_GHOST "rdac checker reports path is ghost" +struct control_mode_page { + unsigned char header[8]; + unsigned char page_code; + unsigned char page_len; + unsigned char dontcare0[3]; + unsigned char tas_bit; + unsigned char dontcare1[6]; +}; + struct rdac_checker_context { void * dummy; }; int libcheck_init (struct checker * c) { + unsigned char cmd[MODE_SEN_SEL_CMDLEN]; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_io_hdr io_hdr; + struct control_mode_page current, changeable; + int set = 0; + + memset(cmd, 0, MODE_SEN_SEL_CMDLEN); + cmd[0] = MODE_SENSE_CMD; + cmd[1] = 0x08; /* DBD bit on */ + cmd[2] = 0xA + (CURRENT_PAGE_CODE_VALUES << 6); + cmd[8] = (sizeof(struct control_mode_page) & 0xff); + + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + memset(sense_b, 0, SENSE_BUFF_LEN); + memset(¤t, 0, sizeof(struct control_mode_page)); + + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = MODE_SEN_SEL_CMDLEN; + io_hdr.mx_sb_len = sizeof(sense_b); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = (sizeof(struct control_mode_page) & 0xff); + io_hdr.dxferp = ¤t; + io_hdr.cmdp = cmd; + io_hdr.sbp = sense_b; + io_hdr.timeout = c->timeout; + + if (ioctl(c->fd, SG_IO, &io_hdr) < 0) + goto out; + + /* check the TAS bit to see if it is already set */ + if ((current.tas_bit >> 6) & 0x1) { + set = 1; + goto out; + } + + /* get the changeble values */ + cmd[2] = 0xA + (CHANGEABLE_PAGE_CODE_VALUES << 6); + io_hdr.dxferp = &changeable; + memset(&changeable, 0, sizeof(struct control_mode_page)); + + if (ioctl(c->fd, SG_IO, &io_hdr) < 0) + goto out; + + /* if TAS bit is not settable exit */ + if (((changeable.tas_bit >> 6) & 0x1) == 0) + goto out; + + /* Now go ahead and set it */ + memset(cmd, 0, MODE_SEN_SEL_CMDLEN); + cmd[0] = MODE_SELECT_CMD; + cmd[1] = 0x1; /* set SP bit on */ + cmd[8] = (sizeof(struct control_mode_page) & 0xff); + + /* use the same buffer as current, only set the tas bit */ + current.page_code = 0xA; + current.page_len = 0xA; + current.tas_bit |= (1 << 6); + + io_hdr.dxfer_direction = SG_DXFER_TO_DEV; + io_hdr.dxferp = ¤t; + + if (ioctl(c->fd, SG_IO, &io_hdr) < 0) + goto out; + + /* Success */ + set = 1; +out: + if (set == 0) + condlog(0, "rdac checker failed to set TAS bit"); return 0; }