From owner-svn-src-head@FreeBSD.ORG Sat Dec 11 00:36:35 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77B7F106566B; Sat, 11 Dec 2010 00:36:35 +0000 (UTC) (envelope-from ken@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4C0B88FC0A; Sat, 11 Dec 2010 00:36:35 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oBB0aZTH090254; Sat, 11 Dec 2010 00:36:35 GMT (envelope-from ken@svn.freebsd.org) Received: (from ken@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oBB0aZCi090252; Sat, 11 Dec 2010 00:36:35 GMT (envelope-from ken@svn.freebsd.org) Message-Id: <201012110036.oBB0aZCi090252@svn.freebsd.org> From: "Kenneth D. Merry" Date: Sat, 11 Dec 2010 00:36:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r216368 - head/sys/dev/mps X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Dec 2010 00:36:35 -0000 Author: ken Date: Sat Dec 11 00:36:35 2010 New Revision: 216368 URL: http://svn.freebsd.org/changeset/base/216368 Log: Fix setting LUN numbers in the mps(4) driver. Prior to this change, the addressing method wasn't getting set, and so the LUN field could be set incorrectly in some instances. This fix should allow for LUN numbers up to 16777215 (and return an error for anything larger, which wouldn't fit into the flat addressing model). Submitted by: scottl (in part) Modified: head/sys/dev/mps/mps_sas.c Modified: head/sys/dev/mps/mps_sas.c ============================================================================== --- head/sys/dev/mps/mps_sas.c Fri Dec 10 23:57:55 2010 (r216367) +++ head/sys/dev/mps/mps_sas.c Sat Dec 11 00:36:35 2010 (r216368) @@ -121,6 +121,7 @@ struct mpssas_devprobe { MALLOC_DEFINE(M_MPSSAS, "MPSSAS", "MPS SAS memory"); +static __inline int mpssas_set_lun(uint8_t *lun, u_int ccblun); static struct mpssas_target * mpssas_alloc_target(struct mpssas_softc *, struct mpssas_target *); static struct mpssas_target * mpssas_find_target(struct mpssas_softc *, int, @@ -163,6 +164,43 @@ static void mpssas_resetdev_complete(str static void mpssas_freeze_device(struct mpssas_softc *, struct mpssas_target *); static void mpssas_unfreeze_device(struct mpssas_softc *, struct mpssas_target *) __unused; +/* + * Abstracted so that the driver can be backwards and forwards compatible + * with future versions of CAM that will provide this functionality. + */ +#define MPS_SET_LUN(lun, ccblun) \ + mpssas_set_lun(lun, ccblun) + +static __inline int +mpssas_set_lun(uint8_t *lun, u_int ccblun) +{ + uint64_t *newlun; + + newlun = (uint64_t *)lun; + *newlun = 0; + if (ccblun <= 0xff) { + /* Peripheral device address method, LUN is 0 to 255 */ + lun[1] = ccblun; + } else if (ccblun <= 0x3fff) { + /* Flat space address method, LUN is <= 16383 */ + scsi_ulto2b(ccblun, lun); + lun[0] |= 0x40; + } else if (ccblun <= 0xffffff) { + /* Extended flat space address method, LUN is <= 16777215 */ + scsi_ulto3b(ccblun, &lun[1]); + /* Extended Flat space address method */ + lun[0] = 0xc0; + /* Length = 1, i.e. LUN is 3 bytes long */ + lun[0] |= 0x10; + /* Extended Address Method */ + lun[0] |= 0x02; + } else { + return (EINVAL); + } + + return (0); +} + static struct mpssas_target * mpssas_alloc_target(struct mpssas_softc *sassc, struct mpssas_target *probe) { @@ -1366,14 +1404,12 @@ mpssas_action_scsiio(struct mpssas_softc break; } - /* XXX Need to handle multi-level LUNs */ - if (csio->ccb_h.target_lun > 255) { + if (MPS_SET_LUN(req->LUN, csio->ccb_h.target_lun) != 0) { mps_free_command(sc, cm); ccb->ccb_h.status = CAM_LUN_INVALID; xpt_done(ccb); return; } - req->LUN[1] = csio->ccb_h.target_lun; if (csio->ccb_h.flags & CAM_CDB_POINTER) bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len);