From owner-freebsd-scsi@FreeBSD.ORG Mon Jul 26 11:07:11 2010 Return-Path: Delivered-To: freebsd-scsi@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 17FB2106566B for ; Mon, 26 Jul 2010 11:07:11 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 0CDF28FC18 for ; Mon, 26 Jul 2010 11:07:11 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o6QB7A1l080804 for ; Mon, 26 Jul 2010 11:07:10 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o6QB7AKP080801 for freebsd-scsi@FreeBSD.org; Mon, 26 Jul 2010 11:07:10 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 26 Jul 2010 11:07:10 GMT Message-Id: <201007261107.o6QB7AKP080801@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-scsi@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-scsi@FreeBSD.org X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jul 2010 11:07:11 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/148083 scsi [aac] Strange device reporting o kern/147704 scsi [mpt] sys/dev/mpt: new chip revision, partially unsupp o kern/146287 scsi [ciss] ciss(4) cannot see more than one SmartArray con o kern/145768 scsi [mpt] can't perform I/O on SAS based SAN disk in freeb o kern/144648 scsi [aac] Strange values of speed and bus width in dmesg o kern/144301 scsi [ciss] [hang] HP proliant server locks when using ciss o kern/142351 scsi [mpt] LSILogic driver performance problems o kern/141934 scsi [cam] [patch] add support for SEAGATE DAT Scopion 130 o kern/134488 scsi [mpt] MPT SCSI driver probes max. 8 LUNs per device o kern/132250 scsi [ciss] ciss driver does not support more then 15 drive o kern/132206 scsi [mpt] system panics on boot when mirroring and 2nd dri p kern/130735 scsi [cam] [patch] pass M_NOWAIT to the malloc() call insid o kern/130621 scsi [mpt] tranfer rate is inscrutable slow when use lsi213 o kern/129602 scsi [ahd] ahd(4) gets confused and wedges SCSI bus o kern/128452 scsi [sa] [panic] Accessing SCSI tape drive randomly crashe o kern/128245 scsi [scsi] "inquiry data fails comparison at DV1 step" [re o kern/127927 scsi [isp] isp(4) target driver crashes kernel when set up o kern/124667 scsi [amd] [panic] FreeBSD-7 kernel page faults at amd-scsi o kern/123674 scsi [ahc] ahc driver dumping f kern/123666 scsi [aac] attach fails with Adaptec SAS RAID 3805 controll o sparc/121676 scsi [iscsi] iscontrol do not connect iscsi-target on sparc o kern/120487 scsi [sg] scsi_sg incompatible with scanners o kern/120247 scsi [mpt] FreeBSD 6.3 and LSI Logic 1030 = only 3.300MB/s o kern/119668 scsi [cam] [patch] certain errors are too verbose comparing o kern/114597 scsi [sym] System hangs at SCSI bus reset with dual HBAs o kern/110847 scsi [ahd] Tyan U320 onboard problem with more than 3 disks o kern/99954 scsi [ahc] reading from DVD failes on 6.x [regression] o kern/94838 scsi Kernel panic while mounting SD card with lock switch o o kern/92798 scsi [ahc] SCSI problem with timeouts o kern/90282 scsi [sym] SCSI bus resets cause loss of ch device o kern/76178 scsi [ahd] Problem with ahd and large SCSI Raid system o kern/74627 scsi [ahc] [hang] Adaptec 2940U2W Can't boot 5.3 s kern/61165 scsi [panic] kernel page fault after calling cam_send_ccb o kern/60641 scsi [sym] Sporadic SCSI bus resets with 53C810 under load o kern/60598 scsi wire down of scsi devices conflicts with config s kern/57398 scsi [mly] Current fails to install on mly(4) based RAID di o kern/52638 scsi [panic] SCSI U320 on SMP server won't run faster than o kern/44587 scsi dev/dpt/dpt.h is missing defines required for DPT_HAND o kern/40895 scsi wierd kernel / device driver bug o kern/39388 scsi ncr/sym drivers fail with 53c810 and more than 256MB m o kern/35234 scsi World access to /dev/pass? (for scanner) requires acce 41 problems total. From owner-freebsd-scsi@FreeBSD.ORG Tue Jul 27 12:38:38 2010 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2D1331065673 for ; Tue, 27 Jul 2010 12:38:38 +0000 (UTC) (envelope-from danny@cs.huji.ac.il) Received: from kabab.cs.huji.ac.il (kabab.cs.huji.ac.il [132.65.16.84]) by mx1.freebsd.org (Postfix) with ESMTP id D27298FC18 for ; Tue, 27 Jul 2010 12:38:37 +0000 (UTC) Received: from pampa.cs.huji.ac.il ([132.65.80.32]) by kabab.cs.huji.ac.il with esmtp id 1OdipG-0008ZN-SQ; Tue, 27 Jul 2010 15:00:02 +0300 X-Mailer: exmh version 2.7.2 01/07/2005 with nmh-1.2 To: freebsd-scsi@freebsd.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Date: Tue, 27 Jul 2010 15:00:02 +0300 From: Daniel Braniss Message-ID: Cc: Dag-Erling =?iso-8859-1?Q?Sm=C3=B8rgrav?= Subject: iscsi_initiator patches X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jul 2010 12:38:38 -0000 hi, though I'm the developer of iscsi_initiator, I don't have (nor want) a commit bit, so could someone with such privilige please apply it? The current distributed version does not realy work. this new version has: - support for header/data digest - no limit on targets (actually 64, but it's a compile option) - some deadlocks fixed. - a memory leak fix the patch is in: ftp://ftp.cs.huji.ac.il/users/danny/freebsd/diffs-2.2.4.2.gz thanks, danny From owner-freebsd-scsi@FreeBSD.ORG Tue Jul 27 18:02:12 2010 Return-Path: Delivered-To: scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BA2F31065670 for ; Tue, 27 Jul 2010 18:02:12 +0000 (UTC) (envelope-from scsi@freebsd.org) Received: from [77.253.87.127] (77-253-87-127.adsl.inetia.pl [77.253.87.127]) by mx1.freebsd.org (Postfix) with ESMTP id 1C9168FC0A for ; Tue, 27 Jul 2010 18:02:11 +0000 (UTC) From: MedsForMen best prices To: scsi@freebsd.org Date: Tue, 27 Jul 2010 20:02:09 +0200 Content-Transfer-Encoding: 8bit Message-Id: <20100727180212.BA2F31065670@hub.freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: Subject: Greetings, scsi, look at our Sale. Abdul Cities X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jul 2010 18:02:12 -0000 If you are unable to see the message below, [1]click here to view. [2]Click to open our shop's website It consists of a single digit computed from the other digits in the message. This form of pedagogy is usually reserved for higher ranking practitioners (for instance, in the kime-no-kata), but are forbidden in contest, and usually prohibited in randori for reasons of safety.Vladimir Dimitrov was an outstanding artist who included bright colors within his art and today we consider his artwork a fauvist type rather than an expressionalism set. If the plans for building and training this division had been carried out as originally laid down by General McNair and his staff, the 65th when it moved overseas in 1945 might have been the most battleworthy of the long line of divisions produced by the Army Ground Forces. Boise (state capital) - Home of Boise State University. Battle of Albelda (851), between Gascons and Muslims. A decision of the highest appeal court in England and Wales, the Supreme Court, is binding on every other court in the hierarchy, which follow its directions.For whom are these ignoble trammels. Certain soil types such as sandy soils are very free draining and rainfall on sandy soil is likely to be absorbed by the ground. The Italian language has a long history, but the modern standard of the language was largely shaped by relatively recent events. Later in the year in Madrid, Nadal helped Spain defeat the United States in the Davis Cup semifinals. The Renaissance reached England through Italian courtiers, who reintroduced artistic, educational and scholary debate from classical antiquity. Taipei is the capital of the ROC. Notable early community broadcasters included Bush Radio in Cape Town and Radio Unitra in Umtata. Soon an uprising in Bulgaria erupted. General William Westmoreland informed Admiral U. His most famous role is Joshamee Gibbs in the Pirates of the Caribbean films. It was built in the 13th century by Llywelyn the Great, Prince of Gwynedd and North Wales. There was no necessary connection between the sign and its meaning. Far-right groups in both countries have been encouraging a revisionist version of history, wherein each group emphasizes only certain positive aspects of their coreligionists throughout the history and ignores the positive aspects of the other. In commerce (retail and wholesale trade), 12. Conducted a worldwide competition for papers on new applications of electric welding. New Brunswick, where about a third of the population is francophone, is the only officially bilingual province.And 1990s (Europe), flat load growth and electricity liberalization also made the addition of large new baseload capacity unattractive. The Redskins were the second team to have a fight song, " Hail to the Redskins ". Smith, Doug, "Raptors hand the reins to Triano", 12 May 2009, accessed 13 May 2009. Hit Chronicle leads pack with 16. In January 1991 Operation Desert Storm commenced, a U. Christianity had become established in the city by the middle of the 3rd century, at which period Saint Sixtus of Reims founded the Reims bishopric.Although Firestone received most of the blame, some blame fell on Ford, which advised customers to under-inflate the tires in order to reduce the risk of vehicle rollovers. Net, News about Llargues competitions. In 1956 the Communist Party leaders of Hanoi admitted to "excesses" in implementing this program and restored a large amount of the land to the original owners.The Internationale is the anthem of the socialist movement, and the communist movement. There is also evidence that this property of dandelion leaves may normalize blood sugar. List of anthems of UN member states. That particular combination surfaced in the first game of the 2003 season, when the team was coached by Steve Spurrier, during a nationally televised game against the New York Jets, which led many sports fans and Redskins faithful alike to point out that they had never seen that particular combination before. © 2009 Louis form the Inc. All rights reserved. [3]Unsubscribe References 1. http://home.planet.nl/~dombu048/girdle20.html 2. http://home.planet.nl/~dombu048/girdle20.html 3. http://home.planet.nl/~dombu048/girdle20.html From owner-freebsd-scsi@FreeBSD.ORG Wed Jul 28 07:37:36 2010 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B43FB1065673 for ; Wed, 28 Jul 2010 07:37:36 +0000 (UTC) (envelope-from des@des.no) Received: from smtp.des.no (smtp.des.no [194.63.250.102]) by mx1.freebsd.org (Postfix) with ESMTP id 78E848FC13 for ; Wed, 28 Jul 2010 07:37:35 +0000 (UTC) Received: from ds4.des.no (des.no [84.49.246.2]) by smtp.des.no (Postfix) with ESMTP id 080521FFC34; Wed, 28 Jul 2010 07:19:44 +0000 (UTC) Received: by ds4.des.no (Postfix, from userid 1001) id CF3048454D; Wed, 28 Jul 2010 09:19:44 +0200 (CEST) From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= To: Daniel Braniss References: Date: Wed, 28 Jul 2010 09:19:44 +0200 In-Reply-To: (Daniel Braniss's message of "Tue, 27 Jul 2010 15:00:02 +0300") Message-ID: <86k4ogoyy7.fsf@ds4.des.no> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (berkeley-unix) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Cc: freebsd-scsi@freebsd.org Subject: Re: iscsi_initiator patches X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2010 07:37:36 -0000 Daniel Braniss writes: > though I'm the developer of iscsi_initiator, I don't have (nor want) > a commit bit, so could someone with such privilige please apply it? Thanks Danny, I'll take care of it. > - no limit on targets (actually 64, but it's a compile option) Are you planning to lift that restriction as we discussed off-list? DES --=20 Dag-Erling Sm=C3=B8rgrav - des@des.no From owner-freebsd-scsi@FreeBSD.ORG Wed Jul 28 07:45:44 2010 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CA45F106564A for ; Wed, 28 Jul 2010 07:45:44 +0000 (UTC) (envelope-from des@des.no) Received: from smtp.des.no (smtp.des.no [194.63.250.102]) by mx1.freebsd.org (Postfix) with ESMTP id 8E4C98FC18 for ; Wed, 28 Jul 2010 07:45:44 +0000 (UTC) Received: from ds4.des.no (des.no [84.49.246.2]) by smtp.des.no (Postfix) with ESMTP id BF6441FFC33; Wed, 28 Jul 2010 07:45:43 +0000 (UTC) Received: by ds4.des.no (Postfix, from userid 1001) id 9668C84516; Wed, 28 Jul 2010 09:45:43 +0200 (CEST) From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= To: Daniel Braniss References: <86k4ogoyy7.fsf@ds4.des.no> Date: Wed, 28 Jul 2010 09:45:43 +0200 In-Reply-To: <86k4ogoyy7.fsf@ds4.des.no> ("Dag-Erling =?utf-8?Q?Sm=C3=B8rg?= =?utf-8?Q?rav=22's?= message of "Wed, 28 Jul 2010 09:19:44 +0200") Message-ID: <86fwz4oxqw.fsf@ds4.des.no> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (berkeley-unix) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Cc: freebsd-scsi@freebsd.org Subject: Re: iscsi_initiator patches X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2010 07:45:44 -0000 Your patch does not apply cleanly to head, nor stable/8. DES --=20 Dag-Erling Sm=C3=B8rgrav - des@des.no From owner-freebsd-scsi@FreeBSD.ORG Wed Jul 28 07:49:00 2010 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8C5A41065678 for ; Wed, 28 Jul 2010 07:49:00 +0000 (UTC) (envelope-from des@des.no) Received: from smtp.des.no (smtp.des.no [194.63.250.102]) by mx1.freebsd.org (Postfix) with ESMTP id 32BB68FC1F for ; Wed, 28 Jul 2010 07:48:59 +0000 (UTC) Received: from ds4.des.no (des.no [84.49.246.2]) by smtp.des.no (Postfix) with ESMTP id 310ED1FFC33; Wed, 28 Jul 2010 07:48:57 +0000 (UTC) Received: by ds4.des.no (Postfix, from userid 1001) id 053DA84516; Wed, 28 Jul 2010 09:48:56 +0200 (CEST) From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= To: Daniel Braniss References: <86k4ogoyy7.fsf@ds4.des.no> <86fwz4oxqw.fsf@ds4.des.no> Date: Wed, 28 Jul 2010 09:48:56 +0200 In-Reply-To: <86fwz4oxqw.fsf@ds4.des.no> ("Dag-Erling =?utf-8?Q?Sm=C3=B8rg?= =?utf-8?Q?rav=22's?= message of "Wed, 28 Jul 2010 09:45:43 +0200") Message-ID: <86bp9soxlj.fsf@ds4.des.no> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Cc: freebsd-scsi@freebsd.org Subject: Re: iscsi_initiator patches X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2010 07:49:00 -0000 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Dag-Erling Sm=C3=B8rgrav writes: > Your patch does not apply cleanly to head, nor stable/8. Here's one that does, but I have no way of testing it. Note that it includes some additional mdoc cleanup. DES --=20 Dag-Erling Sm=C3=B8rgrav - des@des.no --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=iscsi-des.diff Index: sbin/iscontrol/iscsi.conf.5 =================================================================== --- sbin/iscontrol/iscsi.conf.5 (revision 210555) +++ sbin/iscontrol/iscsi.conf.5 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007-2008 Daniel Braniss +.\" Copyright (c) 2007-2010 Daniel Braniss .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -68,6 +68,7 @@ Default is none. .It Cm DataDigest same as for HeaderDigest, but on the data part of the iSCSI PDU. +(not yet tested) .It Cm MaxConnections is the number of simultaneous connections per session, currently only 1. Index: sbin/iscontrol/iscontrol.8 =================================================================== --- sbin/iscontrol/iscontrol.8 (revision 210555) +++ sbin/iscontrol/iscontrol.8 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007-2008 Daniel Braniss +.\" Copyright (c) 2007-2010 Daniel Braniss .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -32,11 +32,12 @@ .Nd login/negotiator/control for an iSCSI initiator session .Sh SYNOPSIS .Nm -.Op Fl vd +.Op Fl dv .Oo -.Op Fl c Ar file +.Fl c Ar file .Op Fl n Ar nickname .Oc +.Op Fl p Ar pidfile .Op Fl t Ar target .Op Ar variable Ns = Ns Ar value .Sh DESCRIPTION @@ -57,26 +58,29 @@ when a SIGHUP signal is received. The flags are as follows: .Bl -tag -width variable=value -.It Fl v -verbose mode. -.It Fl d -do a -.Em discovery session -and exit. .It Fl c Ar file a file containing configuration .Em key-options , see -.Xr iscsi.conf 5 +.Xr iscsi.conf 5 . +.It Fl d +do a +.Em discovery session +and exit. .It Fl n Ar nickname if .Sy -c file is specified, then search for the block named .Em nickname in that file, see -.Xr iscsi.conf 5 +.Xr iscsi.conf 5 . +.It Fl p Ar pidfile +will write the process ID of the session to the specified +.Em pidfile .It Fl t Ar target -is the target's IP address or name +the target's IP address or name. +.It Fl v +verbose mode. .It Ar variable Ns = Ns Ar value see .Xr iscsi.conf 5 @@ -86,13 +90,13 @@ .Sh EXAMPLES .Dl iscontrol -dt myiscsitarget .Pp -will start a +will start a .Em discovery session with the target and print to stdout the list of available targetnames/targetadresses. Note: this listing does not necessarily mean availability, since depending on the target configuration, a discovery session might -not need login/access permission, but a +not need login/access permission, but a .Em full session certainly does. .sp Index: sbin/iscontrol/iscontrol.h =================================================================== --- sbin/iscontrol/iscontrol.h (revision 210555) +++ sbin/iscontrol/iscontrol.h (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without Index: sbin/iscontrol/config.c =================================================================== --- sbin/iscontrol/config.c (revision 210555) +++ sbin/iscontrol/config.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2009 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" /* Index: sbin/iscontrol/fsm.c =================================================================== --- sbin/iscontrol/fsm.c (revision 210555) +++ sbin/iscontrol/fsm.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" typedef enum { @@ -99,26 +99,26 @@ #ifdef notyet { time_t sec; - // make sure we are not in a loop - // XXX: this code has to be tested - sec = time(0) - sess->reconnect_time; - if(sec > (5*60)) { - // if we've been connected for more that 5 minutes - // then just reconnect - sess->reconnect_time = sec; - sess->reconnect_cnt1 = 0; - } - else { - // - sess->reconnect_cnt1++; - if((sec / sess->reconnect_cnt1) < 2) { - // if less that 2 seconds from the last reconnect - // we are most probably looping - syslog(LOG_CRIT, "too many reconnects %d", sess->reconnect_cnt1); - return 0; + // make sure we are not in a loop + // XXX: this code has to be tested + sec = time(0) - sess->reconnect_time; + if(sec > (5*60)) { + // if we've been connected for more that 5 minutes + // then just reconnect + sess->reconnect_time = sec; + sess->reconnect_cnt1 = 0; } + else { + // + sess->reconnect_cnt1++; + if((sec / sess->reconnect_cnt1) < 2) { + // if less that 2 seconds from the last reconnect + // we are most probably looping + syslog(LOG_CRIT, "too many reconnects %d", sess->reconnect_cnt1); + return 0; + } + } } - } #endif sess->reconnect_cnt++; } @@ -140,13 +140,13 @@ if (soc == -1) continue; - // from Patrick.Guelat@imp.ch: - // iscontrol can be called without waiting for the socket entry to time out - val = 1; + // from Patrick.Guelat@imp.ch: + // iscontrol can be called without waiting for the socket entry to time out + val = 1; if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &val, (socklen_t)sizeof(val)) < 0) { - fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n", - errno, strerror(errno)); - } + fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n", + errno, strerror(errno)); + } if(connect(soc, res->ai_addr, res->ai_addrlen) == 0) break; @@ -196,7 +196,7 @@ } sess->flags |= SESS_CONNECTED; return T1; - } + } fprintf(stderr, "errno=%d\n", sv_errno); perror("connect"); @@ -289,7 +289,7 @@ // XXX: this has to go size_t n; n = sizeof(sess->isid); - if(sysctlbyname("net.iscsi.isid", (void *)sess->isid, (size_t *)&n, 0, 0) != 0) + if(sysctlbyname("net.iscsi_initiator.isid", (void *)sess->isid, (size_t *)&n, 0, 0) != 0) perror("sysctlbyname"); } if(ioctl(fd, ISCSISETSES, &n)) { @@ -343,29 +343,29 @@ } } -static void +static int doCAM(isess_t *sess) { char pathstr[1024]; union ccb *ccb; - int i; + int i, n; if(ioctl(sess->fd, ISCSIGETCAM, &sess->cam) != 0) { syslog(LOG_WARNING, "ISCSIGETCAM failed: %d", errno); - return; + return 0; } - debug(2, "nluns=%d", sess->cam.target_nluns); + debug(1, "nluns=%d", sess->cam.target_nluns); /* | for now will do this for each lun ... */ - for(i = 0; i < sess->cam.target_nluns; i++) { + for(n = i = 0; i < sess->cam.target_nluns; i++) { debug(2, "CAM path_id=%d target_id=%d target_lun=%d", sess->cam.path_id, sess->cam.target_id, sess->cam.target_lun[i]); sess->camdev = cam_open_btl(sess->cam.path_id, sess->cam.target_id, - sess->cam.target_lun[i], O_RDWR, NULL); + i, O_RDWR, NULL); if(sess->camdev == NULL) { - syslog(LOG_WARNING, "%s", cam_errbuf); + //syslog(LOG_WARNING, "%s", cam_errbuf); debug(3, "%s", cam_errbuf); continue; } @@ -378,20 +378,21 @@ ccb->ccb_h.func_code = XPT_REL_SIMQ; ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; ccb->crs.openings = sess->op->tags; - if(cam_send_ccb(sess->camdev, ccb) < 0) - syslog(LOG_WARNING, "%s", cam_errbuf); + debug(2, "%s", cam_errbuf); else if((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { syslog(LOG_WARNING, "XPT_REL_SIMQ CCB failed"); // cam_error_print(sess->camdev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } - else + else { + n++; syslog(LOG_INFO, "%s tagged openings now %d\n", pathstr, ccb->crs.openings); - + } cam_freeccb(ccb); cam_close_device(sess->camdev); } + return n; } static trans_t @@ -417,7 +418,15 @@ perror("daemon"); exit(1); } + if(sess->op->pidfile != NULL) { + FILE *pidf; + pidf = fopen(sess->op->pidfile, "w"); + if(pidf != NULL) { + fprintf(pidf, "%d\n", getpid()); + fclose(pidf); + } + } openlog("iscontrol", LOG_CONS|LOG_PERROR|LOG_PID|LOG_NDELAY, LOG_KERN); syslog(LOG_INFO, "running"); @@ -426,7 +435,11 @@ perror("ISCSISTART"); return -1; } - doCAM(sess); + if(doCAM(sess) == 0) { + syslog(LOG_WARNING, "no device found"); + ioctl(sess->fd, ISCSISTOP); + return T15; + } } else { @@ -449,7 +462,8 @@ sess->flags |= SESS_FULLFEATURE; sess->flags &= ~(SESS_REDIRECT | SESS_RECONNECT); - printf("iscontrol: supervise starting main loop\n"); + if(vflag) + printf("iscontrol: supervise starting main loop\n"); /* | the main loop - actually do nothing | all the work is done inside the kernel @@ -468,14 +482,14 @@ } if(sess->flags & SESS_DISCONNECT) { + sess->flags &= ~SESS_FULLFEATURE; + return T9; + } + else { val = 0; if(ioctl(sess->fd, ISCSISTOP, &val)) { perror("ISCSISTOP"); } - sess->flags &= ~SESS_FULLFEATURE; - return T9; - } - else { sess->flags |= SESS_INITIALLOGIN1; } return T8; @@ -490,7 +504,7 @@ debug_called(3); len = pp->ds_len; - ptr = pp->ds; + ptr = pp->ds_addr; while(len > 0) { if(*ptr != 0) printf("%s\n", ptr); @@ -579,8 +593,13 @@ static int handleLogoutResp(isess_t *sess, pdu_t *pp) { - if(sess->flags & SESS_DISCONNECT) + if(sess->flags & SESS_DISCONNECT) { + int val = 0; + if(ioctl(sess->fd, ISCSISTOP, &val)) { + perror("ISCSISTOP"); + } return 0; + } return T13; } Index: sbin/iscontrol/login.c =================================================================== --- sbin/iscontrol/login.c (revision 210555) +++ sbin/iscontrol/login.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" static char *status_class1[] = { @@ -107,7 +107,7 @@ debug_called(3); len = pp->ds_len; - ptr = (char *)pp->ds; + ptr = (char *)pp->ds_addr; klen = strlen(key); while(len > klen) { if(strncmp(key, ptr, klen) == 0) @@ -163,7 +163,7 @@ debug_called(3); len = pp->ds_len; - ptr = (char *)pp->ds; + ptr = (char *)pp->ds_addr; while(len > 0) { if(vflag > 1) printf("got: len=%d %s\n", len, ptr); Index: sbin/iscontrol/pdu.c =================================================================== --- sbin/iscontrol/pdu.c (revision 210555) +++ sbin/iscontrol/pdu.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,10 +43,9 @@ #include #include -#include "iscsi.h" #include "iscontrol.h" -static void pukeText(char *it, pdu_t *pp); +static void pukeText(char *it, pdu_t *pp); int xmitpdu(isess_t *sess, pdu_t *pp) @@ -85,7 +84,7 @@ int res; pp->ahs_size = 8 * 1024; - if((pp->ahs = malloc(pp->ahs_size)) == NULL) { + if((pp->ahs_addr = malloc(pp->ahs_size)) == NULL) { fprintf(stderr, "out of mem!"); return -1; } @@ -126,16 +125,16 @@ if((pp->ds_len + len) > pp->ds_size) { u_char *np; - np = realloc(pp->ds, pp->ds_size + len + FUDGE); + np = realloc(pp->ds_addr, pp->ds_size + len + FUDGE); if(np == NULL) { free(str); //XXX: out of memory! return -1; } - pp->ds = np; + pp->ds_addr = np; pp->ds_size += len + FUDGE; } - memcpy(pp->ds + pp->ds_len, str, len); + memcpy(pp->ds_addr + pp->ds_len, str, len); pp->ds_len += len; free(str); return len; @@ -145,12 +144,12 @@ freePDU(pdu_t *pp) { if(pp->ahs_size) - free(pp->ahs); + free(pp->ahs_addr); if(pp->ds_size) - free(pp->ds); + free(pp->ds_addr); bzero(&pp->ipdu, sizeof(union ipdu_u)); - pp->ahs = NULL; - pp->ds = NULL; + pp->ahs_addr = NULL; + pp->ds_addr = NULL; pp->ahs_size = 0; pp->ds_size = pp->ds_len = 0; } @@ -163,7 +162,7 @@ size_t len, n; len = pp->ds_len; - ptr = (char *)pp->ds; + ptr = (char *)pp->ds_addr; cmd = pp->ipdu.bhs.opcode; printf("%s: cmd=0x%x len=%d\n", it, cmd, (int)len); Index: sbin/iscontrol/misc.c =================================================================== --- sbin/iscontrol/misc.c (revision 210555) +++ sbin/iscontrol/misc.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without Index: sbin/iscontrol/Makefile =================================================================== --- sbin/iscontrol/Makefile (revision 210555) +++ sbin/iscontrol/Makefile (working copy) @@ -1,12 +1,13 @@ # $FreeBSD$ -SRCS= iscontrol.c pdu.c fsm.c config.c login.c auth_subr.c misc.c -PROG= iscontrol -DPADD= ${LIBCAM} ${LIBMD} -LDADD= -lcam -lmd +SRCS= iscontrol.c pdu.c fsm.c config.c login.c auth_subr.c misc.c +PROG= iscontrol +DPADD= ${LIBCAM} ${LIBMD} +LDADD= -lcam -lmd +S= ${.CURDIR}/../../sys WARNS?= 2 -CFLAGS += -I${.CURDIR}/../../sys/dev/iscsi/initiator +CFLAGS += -I$S #CFLAGS += -g -DDEBUG MAN= iscsi.conf.5 iscontrol.8 Index: sbin/iscontrol/auth_subr.c =================================================================== --- sbin/iscontrol/auth_subr.c (revision 210555) +++ sbin/iscontrol/auth_subr.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" static int Index: sbin/iscontrol/iscontrol.c =================================================================== --- sbin/iscontrol/iscontrol.c (revision 210555) +++ sbin/iscontrol/iscontrol.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,16 +53,12 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" -#define USAGE "[-v] [-d] [-c config] [-n name] [-t target] " -#define OPTIONS "vdc:t:n:" +#define USAGE "[-v] [-d] [-c config] [-n name] [-t target] [-p pidfile]" +#define OPTIONS "vdc:t:n:p:" -#ifndef DEBUG -//int vflag; -#endif - token_t AuthMethods[] = { {"None", NONE}, {"KRB5", KRB5}, @@ -128,7 +124,7 @@ main(int cc, char **vv) { int ch, disco; - char *pname, *p, *q, *ta, *kw; + char *pname, *pidfile, *p, *q, *ta, *kw; isc_opt_t *op; FILE *fd; @@ -141,6 +137,7 @@ kw = ta = 0; disco = 0; + pidfile = NULL; while((ch = getopt(cc, vv, OPTIONS)) != -1) { switch(ch) { @@ -163,6 +160,9 @@ case 'n': kw = optarg; break; + case 'p': + pidfile = optarg; + break; default: badu: fprintf(stderr, "Usage: %s %s\n", pname, USAGE); @@ -225,7 +225,7 @@ op->sessionType = "Discovery"; op->targetName = 0; } - + op->pidfile = pidfile; fsm(op); exit(0); Index: sbin/iscontrol/pdu.h =================================================================== --- sbin/iscontrol/pdu.h (revision 210555) +++ sbin/iscontrol/pdu.h (working copy) @@ -1,134 +0,0 @@ -/*- - * Copyright (c) 2005 Daniel Braniss - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - | $Id: pdu.h,v 2.1 2006/11/12 08:06:51 danny Exp $ - */ - -/* - | keep in BIG endian order (network byte order). - */ - -typedef struct login_req { - char cmd; // 0x03 - - u_char NSG:2; - u_char CSG:2; - u_char _:2; - u_char C:1; - u_char T:1; - - char v_max; - char v_min; - - int len; // remapped via standard bhs - char isid[6]; - short tsih; - int itt; // Initiator Task Tag; - - int CID:16; - int rsv:16; - - int cmdSN; - int expStatSN; - int unused[4]; -} login_req_t; - -typedef struct login_rsp { - char cmd; // 0x23 - u_char NSG:2; - u_char CSG:2; - u_char _1:2; - u_char C:1; - u_char T:1; - - char v_max; - char v_act; - - int len; // remapped via standard bhs - char isid[6]; - short tsih; - int itt; // Initiator Task Tag; - int _2; - rsp_sn_t sn; - int status:16; - int _3:16; - int _4[2]; -} login_rsp_t; - -typedef struct text_req { - char cmd; // 0x04 - - u_char _1:6; - u_char C:1; // Continuation - u_char F:1; // Final - char _2[2]; - - int len; - int itt; // Initiator Task Tag - int LUN[2]; - int ttt; // Target Transfer Tag - int cmdSN; - int expStatSN; - int unused[4]; -} text_req_t; - -/* - | Responses - */ -typedef struct logout_req { - char cmd; // 0x06 - char reason; // 0 - close session - // 1 - close connection - // 2 - remove the connection for recovery - char _2[2]; - - int len; - int _r[2]; - int itt; // Initiator Task Tag; - - u_int CID:16; - u_int rsv:16; - - int cmdSN; - int expStatSN; - int unused[4]; -} logout_req_t; - -typedef struct logout_rsp { - char cmd; // 0x26 - char cbits; - char _1[2]; - int len; - int _2[2]; - int itt; - int _3; - rsp_sn_t sn; - short time2wait; - short time2retain; - int _4; -} logout_rsp_t; Index: sys/dev/iscsi/initiator/isc_cam.c =================================================================== --- sys/dev/iscsi/initiator/isc_cam.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_cam.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,9 @@ * SUCH DAMAGE. * */ - +/* + | $Id: isc_cam.c 998 2009-12-20 10:32:45Z danny $ + */ #include __FBSDID("$FreeBSD$"); @@ -43,6 +45,7 @@ #include #include #include +#include #include #include @@ -53,52 +56,72 @@ #include #include -// XXX: untested/incomplete -void -ic_freeze(isc_session_t *sp) +static void +_inq(struct cam_sim *sim, union ccb *ccb) { + struct ccb_pathinq *cpi = &ccb->cpi; + isc_session_t *sp = cam_sim_softc(sim); + debug_called(8); -#if 0 - sdebug(2, "freezing path=%p", sp->cam_path == NULL? 0: sp->cam_path); - if((sp->cam_path != NULL) && !(sp->flags & ISC_FROZEN)) { - xpt_freeze_devq(sp->cam_path, 1); - } + debug(3, "sid=%d target=%d lun=%d", sp->sid, ccb->ccb_h.target_id, ccb->ccb_h.target_lun); + + cpi->version_num = 1; /* XXX??? */ + cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_32; + cpi->target_sprt = 0; + cpi->hba_misc = 0; + cpi->hba_eng_cnt = 0; + cpi->max_target = 0; //ISCSI_MAX_TARGETS - 1; + cpi->initiator_id = ISCSI_MAX_TARGETS; + cpi->max_lun = sp->opt.maxluns - 1; + cpi->bus_id = cam_sim_bus(sim); + cpi->base_transfer_speed = 3300; // 40000; // XXX: + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + cpi->transport = XPORT_ISCSI; + cpi->transport_version = 0; + cpi->ccb_h.status = CAM_REQ_CMP; +#if defined(KNOB_VALID_ADDRESS) + cpi->transport = XPORT_ISCSI; + cpi->transport_version = 0; #endif - sp->flags |= ISC_FROZEN; } -// XXX: untested/incomplete -void -ic_release(isc_session_t *sp) +static __inline int +_scsi_encap(struct cam_sim *sim, union ccb *ccb) { - debug_called(8); -#if 0 - sdebug(2, "release path=%p", sp->cam_path == NULL? 0: sp->cam_path); - if((sp->cam_path != NULL) && (sp->flags & ISC_FROZEN)) { - xpt_release_devq(sp->cam_path, 1, TRUE); - } + int ret; + +#if __FreeBSD_version < 700000 + ret = scsi_encap(sim, ccb); +#else + isc_session_t *sp = cam_sim_softc(sim); + + mtx_unlock(&sp->cam_mtx); + ret = scsi_encap(sim, ccb); + mtx_lock(&sp->cam_mtx); #endif - sp->flags &= ~ISC_FROZEN; + return ret; } void ic_lost_target(isc_session_t *sp, int target) { - struct isc_softc *isp = sp->isc; - debug_called(8); - sdebug(2, "target=%d", target); + sdebug(2, "lost target=%d", target); + if(sp->cam_path != NULL) { - mtx_lock(&isp->cam_mtx); + mtx_lock(&sp->cam_mtx); xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL); xpt_free_path(sp->cam_path); - mtx_unlock(&isp->cam_mtx); + mtx_unlock(&sp->cam_mtx); sp->cam_path = 0; // XXX } } static void -_scan_callback(struct cam_periph *periph, union ccb *ccb) +scan_callback(struct cam_periph *periph, union ccb *ccb) { isc_session_t *sp = (isc_session_t *)ccb->ccb_h.spriv_ptr0; @@ -106,63 +129,52 @@ free(ccb, M_TEMP); - if(sp->flags & ISC_FFPWAIT) { - sp->flags &= ~ISC_FFPWAIT; + if(sp->flags & ISC_SCANWAIT) { + sp->flags &= ~ISC_SCANWAIT; wakeup(sp); } } -static void -_scan_target(isc_session_t *sp, int target) +static int +ic_scan(isc_session_t *sp) { - union ccb *ccb; + union ccb *ccb; debug_called(8); - sdebug(2, "target=%d", target); + sdebug(2, "scanning sid=%d", sp->sid); if((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) { xdebug("scan failed (can't allocate CCB)"); - return; + return ENOMEM; // XXX } - CAM_LOCK(sp->isc); + + sp->flags &= ~ISC_CAMDEVS; + sp->flags |= ISC_SCANWAIT; + + CAM_LOCK(sp); + if(xpt_create_path(&sp->cam_path, xpt_periph, cam_sim_path(sp->cam_sim), + 0, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xdebug("can't create cam path"); + CAM_UNLOCK(sp); + free(ccb, M_TEMP); + return ENODEV; // XXX + } xpt_setup_ccb(&ccb->ccb_h, sp->cam_path, 5/*priority (low)*/); ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = _scan_callback; + ccb->ccb_h.cbfcnp = scan_callback; ccb->crcn.flags = CAM_FLAG_NONE; ccb->ccb_h.spriv_ptr0 = sp; xpt_action(ccb); - CAM_UNLOCK(sp->isc); -} + CAM_UNLOCK(sp); -int -ic_fullfeature(struct cdev *dev) -{ - struct isc_softc *isp = dev->si_drv1; - isc_session_t *sp = (isc_session_t *)dev->si_drv2; - - debug_called(8); - sdebug(3, "dev=%d sc=%p", dev2unit(dev), isp); - - sp->flags &= ~ISC_FFPHASE; - sp->flags |= ISC_FFPWAIT; - - CAM_LOCK(isp); - if(xpt_create_path(&sp->cam_path, xpt_periph, cam_sim_path(sp->isc->cam_sim), - sp->sid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xdebug("can't create cam path"); - CAM_UNLOCK(isp); - return ENODEV; // XXX - } - CAM_UNLOCK(isp); - - _scan_target(sp, sp->sid); - - while(sp->flags & ISC_FFPWAIT) + while(sp->flags & ISC_SCANWAIT) tsleep(sp, PRIBIO, "ffp", 5*hz); // the timeout time should // be configurable + sdebug(2, "# of luns=%d", sp->target_nluns); + if(sp->target_nluns > 0) { - sp->flags |= ISC_FFPHASE; + sp->flags |= ISC_CAMDEVS; return 0; } @@ -170,110 +182,25 @@ } static void -_inq(struct cam_sim *sim, union ccb *ccb, int maxluns) -{ - struct ccb_pathinq *cpi = &ccb->cpi; - - debug_called(4); - - cpi->version_num = 1; /* XXX??? */ - cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_32; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = ISCSI_MAX_TARGETS - 1; - cpi->initiator_id = ISCSI_MAX_TARGETS; - cpi->max_lun = maxluns; - cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 3300; - strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN); - strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); - cpi->unit_number = cam_sim_unit(sim); - cpi->transport = XPORT_ISCSI; - cpi->transport_version = 0; - cpi->ccb_h.status = CAM_REQ_CMP; -} - -static __inline int -_scsi_encap(struct cam_sim *sim, union ccb *ccb) -{ - int ret; - -#if __FreeBSD_version < 700000 - ret = scsi_encap(sim, ccb); -#else - struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim); - - mtx_unlock(&isp->cam_mtx); - ret = scsi_encap(sim, ccb); - mtx_lock(&isp->cam_mtx); -#endif - return ret; -} - -static void ic_action(struct cam_sim *sim, union ccb *ccb) { + isc_session_t *sp = cam_sim_softc(sim); struct ccb_hdr *ccb_h = &ccb->ccb_h; - struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim); - isc_session_t *sp; debug_called(8); - if((ccb_h->target_id != CAM_TARGET_WILDCARD) && (ccb_h->target_id < MAX_SESSIONS)) - sp = isp->sessions[ccb_h->target_id]; - else - sp = NULL; - ccb_h->spriv_ptr0 = sp; - - debug(4, "func_code=0x%x flags=0x%x status=0x%x target=%d lun=%d retry_count=%d timeout=%d", + sdebug(4, "func_code=0x%x flags=0x%x status=0x%x target=%d lun=%d retry_count=%d timeout=%d", ccb_h->func_code, ccb->ccb_h.flags, ccb->ccb_h.status, ccb->ccb_h.target_id, ccb->ccb_h.target_lun, ccb->ccb_h.retry_count, ccb_h->timeout); - /* - | first quick check - */ + if(sp == NULL) { + xdebug("sp == NULL! cannot happen"); + return; + } switch(ccb_h->func_code) { - default: - // XXX: maybe check something else? - break; - - case XPT_SCSI_IO: - case XPT_RESET_DEV: - case XPT_GET_TRAN_SETTINGS: - case XPT_SET_TRAN_SETTINGS: - case XPT_CALC_GEOMETRY: - if(sp == NULL) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; -#if __FreeBSD_version < 700000 - XPT_DONE(isp, ccb); -#else - xpt_done(ccb); -#endif - return; - } - break; - case XPT_PATH_INQ: - case XPT_NOOP: - if(sp == NULL && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; -#if __FreeBSD_version < 700000 - XPT_DONE(isp, ccb); -#else - xpt_done(ccb); -#endif - debug(4, "status = CAM_DEV_NOT_THERE"); - return; - } - } - - switch(ccb_h->func_code) { - - case XPT_PATH_INQ: - _inq(sim, ccb, (sp? sp->opt.maxluns: ISCSI_MAX_LUNS) - 1); + _inq(sim, ccb); break; case XPT_RESET_BUS: // (can just be a stub that does nothing and completes) @@ -310,14 +237,35 @@ struct ccb_calc_geometry *ccg; ccg = &ccb->ccg; - debug(6, "XPT_CALC_GEOMETRY vsize=%jd bsize=%d", ccg->volume_size, ccg->block_size); + debug(4, "sid=%d target=%d lun=%d XPT_CALC_GEOMETRY vsize=%jd bsize=%d", + sp->sid, ccb->ccb_h.target_id, ccb->ccb_h.target_lun, + ccg->volume_size, ccg->block_size); if(ccg->block_size == 0 || (ccg->volume_size < ccg->block_size)) { // print error message ... /* XXX: what error is appropiate? */ break; - } else + } + else { + int lun, *off, boff; + + lun = ccb->ccb_h.target_lun; + if(lun > ISCSI_MAX_LUNS) { + // XXX: + xdebug("lun %d > ISCSI_MAX_LUNS!\n", lun); + lun %= ISCSI_MAX_LUNS; + } + off = &sp->target_lun[lun / (sizeof(int)*8)]; + boff = BIT(lun % (sizeof(int)*8)); + debug(4, "sp->target_nluns=%d *off=%x boff=%x", + sp->target_nluns, *off, boff); + + if((*off & boff) == 0) { + sp->target_nluns++; + *off |= boff; + } cam_calc_geometry(ccg, /*extended*/1); + } break; } @@ -327,7 +275,7 @@ break; } #if __FreeBSD_version < 700000 - XPT_DONE(isp, ccb); + XPT_DONE(sp, ccb); #else xpt_done(ccb); #endif @@ -337,102 +285,102 @@ static void ic_poll(struct cam_sim *sim) { - debug_called(8); + debug_called(4); } int ic_getCamVals(isc_session_t *sp, iscsi_cam_t *cp) { - int i; - debug_called(8); - if(sp && sp->isc->cam_sim) { - cp->path_id = cam_sim_path(sp->isc->cam_sim); - cp->target_id = sp->sid; - cp->target_nluns = sp->target_nluns; // XXX: -1? - for(i = 0; i < cp->target_nluns; i++) - cp->target_lun[i] = sp->target_lun[i]; + if(sp && sp->cam_sim) { + cp->path_id = cam_sim_path(sp->cam_sim); + cp->target_id = 0; + cp->target_nluns = ISCSI_MAX_LUNS; // XXX: -1? return 0; } return ENXIO; } void -ic_destroy(struct isc_softc *isp) +ic_destroy(isc_session_t *sp ) { debug_called(8); - CAM_LOCK(isp); // can't harm :-) + if(sp->cam_path != NULL) { + sdebug(2, "name=%s unit=%d", + cam_sim_name(sp->cam_sim), cam_sim_unit(sp->cam_sim)); + CAM_LOCK(sp); +#if 0 + xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL); +#else + xpt_async(XPT_RESET_BUS, sp->cam_path, NULL); +#endif + xpt_free_path(sp->cam_path); + xpt_bus_deregister(cam_sim_path(sp->cam_sim)); + cam_sim_free(sp->cam_sim, TRUE /*free_devq*/); - xpt_async(AC_LOST_DEVICE, isp->cam_path, NULL); - xpt_free_path(isp->cam_path); - - xpt_bus_deregister(cam_sim_path(isp->cam_sim)); - cam_sim_free(isp->cam_sim, TRUE /*free_devq*/); - - CAM_UNLOCK(isp); + CAM_UNLOCK(sp); + sdebug(2, "done"); + } } int -ic_init(struct isc_softc *isp) +ic_init(isc_session_t *sp) { struct cam_sim *sim; struct cam_devq *devq; - struct cam_path *path; + debug_called(8); + if((devq = cam_simq_alloc(256)) == NULL) return ENOMEM; #if __FreeBSD_version >= 700000 - mtx_init(&isp->cam_mtx, "isc-cam", NULL, MTX_DEF); + mtx_init(&sp->cam_mtx, "isc-cam", NULL, MTX_DEF); #else isp->cam_mtx = Giant; #endif - sim = cam_sim_alloc(ic_action, ic_poll, - "iscsi", isp, 0/*unit*/, + sim = cam_sim_alloc(ic_action, + ic_poll, + "iscsi", + sp, + sp->sid, // unit #if __FreeBSD_version >= 700000 - &isp->cam_mtx, + &sp->cam_mtx, #endif - 1/*max_dev_transactions*/, - 100/*max_tagged_dev_transactions*/, + 1, // max_dev_transactions + 0, // max_tagged_dev_transactions devq); if(sim == NULL) { cam_simq_free(devq); #if __FreeBSD_version >= 700000 - mtx_destroy(&isp->cam_mtx); + mtx_destroy(&sp->cam_mtx); #endif return ENXIO; } - CAM_LOCK(isp); + + CAM_LOCK(sp); if(xpt_bus_register(sim, #if __FreeBSD_version >= 700000 NULL, #endif - 0/*bus_number*/) != CAM_SUCCESS) - goto bad; + 0/*bus_number*/) != CAM_SUCCESS) { - if(xpt_create_path(&path, xpt_periph, cam_sim_path(sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_bus_deregister(cam_sim_path(sim)); - goto bad; + cam_sim_free(sim, /*free_devq*/TRUE); + CAM_UNLOCK(sp); +#if __FreeBSD_version >= 700000 + mtx_destroy(&sp->cam_mtx); +#endif + return ENXIO; } + sp->cam_sim = sim; + CAM_UNLOCK(sp); - CAM_UNLOCK(isp); + sdebug(1, "cam subsystem initialized"); - isp->cam_sim = sim; - isp->cam_path = path; + ic_scan(sp); - debug(2, "cam subsystem initialized"); // XXX: add dev ... - debug(4, "sim=%p path=%p", sim, path); return 0; - - bad: - cam_sim_free(sim, /*free_devq*/TRUE); - CAM_UNLOCK(isp); -#if __FreeBSD_version >= 700000 - mtx_destroy(&isp->cam_mtx); -#endif - return ENXIO; } Index: sys/dev/iscsi/initiator/iscsi.h =================================================================== --- sys/dev/iscsi/initiator/iscsi.h (revision 210555) +++ sys/dev/iscsi/initiator/iscsi.h (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * $FreeBSD$ */ /* - | $Id: iscsi.h,v 1.17 2006/12/01 09:10:17 danny Exp danny $ + | $Id: iscsi.h 743 2009-08-08 10:54:53Z danny $ */ #define TRUE 1 #define FALSE 0 @@ -37,11 +37,7 @@ #include #define ISCSIDEV "iscsi" - -#define ISCSI_MAX_TARGETS 4 //64 - -#define ISCSI_MAX_LUNS 4 - +#define ISCSI_MAX_TARGETS 64 /* | iSCSI commands */ @@ -422,13 +418,13 @@ */ typedef struct { union ipdu_u ipdu; + u_int hdr_dig; // header digest - ahs_t *ahs; + ahs_t *ahs_addr; u_int ahs_len; u_int ahs_size; // the allocated size - u_int hdr_dig; // header digest - u_char *ds; + u_char *ds_addr; u_int ds_len; u_int ds_size; // the allocated size u_int ds_dig; // data digest @@ -474,6 +470,7 @@ u_char tgtChapID; char *tgtChapDigest; char *iqn; + char *pidfile; } isc_opt_t; /* @@ -498,7 +495,6 @@ path_id_t path_id; target_id_t target_id; int target_nluns; - lun_id_t target_lun[ISCSI_MAX_LUNS]; } iscsi_cam_t; #define ISCSIGETCAM _IOR('i', 33, iscsi_cam_t) Index: sys/dev/iscsi/initiator/isc_soc.c =================================================================== --- sys/dev/iscsi/initiator/isc_soc.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_soc.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,10 +25,8 @@ * */ /* - | iSCSI - | $Id: isc_soc.c,v 1.26 2007/05/19 06:09:01 danny Exp danny $ + | $Id: isc_soc.c 998 2009-12-20 10:32:45Z danny $ */ - #include __FBSDID("$FreeBSD$"); @@ -66,9 +64,7 @@ #endif #ifdef USE_MBUF - static int ou_refcnt = 0; - /* | function for freeing external storage for mbuf */ @@ -79,7 +75,7 @@ if(pq->buf != NULL) { debug(3, "ou_refcnt=%d a=%p b=%p", ou_refcnt, a, pq->buf); - free(pq->buf, M_ISCSI); + free(pq->buf, M_ISCSIBUF); pq->buf = NULL; } } @@ -88,84 +84,96 @@ isc_sendPDU(isc_session_t *sp, pduq_t *pq) { struct mbuf *mh, **mp; - pdu_t *pp = &pq->pdu; - int len, error; + pdu_t *pp = &pq->pdu; + int len, error; debug_called(8); /* | mbuf for the iSCSI header */ MGETHDR(mh, M_TRYWAIT, MT_DATA); - mh->m_len = mh->m_pkthdr.len = sizeof(union ipdu_u); mh->m_pkthdr.rcvif = NULL; - MH_ALIGN(mh, sizeof(union ipdu_u)); - bcopy(&pp->ipdu, mh->m_data, sizeof(union ipdu_u)); mh->m_next = NULL; + mh->m_len = sizeof(union ipdu_u); - if(sp->hdrDigest) - pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0); + if(ISOK2DIG(sp->hdrDigest, pp)) { + pp->hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0); + mh->m_len += sizeof(pp->hdr_dig); + if(pp->ahs_len) { + debug(2, "ahs_len=%d", pp->ahs_len); + pp->hdr_dig = sp->hdrDigest(&pp->ahs_addr, pp->ahs_len, pp->hdr_dig); + } + debug(3, "pp->hdr_dig=%04x", htonl(pp->hdr_dig)); + } if(pp->ahs_len) { /* | Add any AHS to the iSCSI hdr mbuf - | XXX Assert: (mh->m_pkthdr.len + pp->ahs_len) < MHLEN */ - bcopy(pp->ahs, (mh->m_data + mh->m_len), pp->ahs_len); - mh->m_len += pp->ahs_len; - mh->m_pkthdr.len += pp->ahs_len; - - if(sp->hdrDigest) - pq->pdu.hdr_dig = sp->hdrDigest(&pp->ahs, pp->ahs_len, pq->pdu.hdr_dig); + if((mh->m_len + pp->ahs_len) < MHLEN) { + MH_ALIGN(mh, mh->m_len + pp->ahs_len); + bcopy(&pp->ipdu, mh->m_data, mh->m_len); + bcopy(pp->ahs_addr, mh->m_data + mh->m_len, pp->ahs_len); + mh->m_len += pp->ahs_len; + } + else + panic("len AHS=%d too big, not impleneted yet", pp->ahs_len); } - if(sp->hdrDigest) { - debug(2, "hdr_dig=%x", pq->pdu.hdr_dig); - /* - | Add header digest to the iSCSI hdr mbuf - | XXX Assert: (mh->m_pkthdr.len + 4) < MHLEN - */ - bcopy(&pp->hdr_dig, (mh->m_data + mh->m_len), sizeof(int)); - mh->m_len += sizeof(int); - mh->m_pkthdr.len += sizeof(int); + else { + MH_ALIGN(mh, mh->m_len); + bcopy(&pp->ipdu, mh->m_data, mh->m_len); } + mh->m_pkthdr.len = mh->m_len; mp = &mh->m_next; - if(pq->pdu.ds) { - struct mbuf *md; - int off = 0; + if(pp->ds_len && pq->pdu.ds_addr) { + struct mbuf *md; + int off = 0; len = pp->ds_len; - while(len & 03) // the specs say it must be int alligned - len++; while(len > 0) { - int l; - + int l; + MGET(md, M_TRYWAIT, MT_DATA); md->m_ext.ref_cnt = &ou_refcnt; - l = min(MCLBYTES, len); - debug(5, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l); - MEXTADD(md, pp->ds + off, l, ext_free, pp->ds + off, pq, 0, EXT_EXTREF); - md->m_len = l; - md->m_next = NULL; - mh->m_pkthdr.len += l; - *mp = md; - mp = &md->m_next; - len -= l; - off += l; - } + l = min(MCLBYTES, len); + debug(4, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l); + MEXTADD(md, pp->ds_addr + off, l, ext_free, +#if __FreeBSD_version >= 800000 + pp->ds_addr + off, +#endif + pq, 0, EXT_EXTREF); + md->m_len = l; + md->m_next = NULL; + mh->m_pkthdr.len += l; + *mp = md; + mp = &md->m_next; + len -= l; + off += l; + } + if(((pp->ds_len & 03) != 0) || ISOK2DIG(sp->dataDigest, pp)) { + MGET(md, M_TRYWAIT, MT_DATA); + if(pp->ds_len & 03) + len = 4 - (pp->ds_len & 03); + else + len = 0; + md->m_len = len; + if(ISOK2DIG(sp->dataDigest, pp)) + md->m_len += sizeof(pp->ds_dig); + MH_ALIGN(md, md->m_len); + if(ISOK2DIG(sp->dataDigest, pp)) { + pp->ds_dig = sp->dataDigest(pp->ds_addr, pp->ds_len, 0); + if(len) { + bzero(md->m_data, len); // RFC says SHOULD be 0 + pp->ds_dig = sp->dataDigest(md->m_data, len, pp->ds_dig); + } + bcopy(&pp->ds_dig, md->m_data+len, sizeof(pp->ds_dig)); + } + md->m_next = NULL; + mh->m_pkthdr.len += md->m_len; + *mp = md; + } } - if(sp->dataDigest) { - struct mbuf *me; - - pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0); - - MGET(me, M_TRYWAIT, MT_DATA); - me->m_len = sizeof(int); - MH_ALIGN(mh, sizeof(int)); - bcopy(&pp->ds_dig, me->m_data, sizeof(int)); - me->m_next = NULL; - mh->m_pkthdr.len += sizeof(int); - *mp = me; - } if((error = sosend(sp->soc, NULL, NULL, mh, 0, 0, sp->td)) != 0) { - sdebug(3, "error=%d", error); + sdebug(2, "error=%d", error); return error; } sp->stats.nsent++; @@ -191,39 +199,46 @@ iv->iov_base = &pp->ipdu; iv->iov_len = sizeof(union ipdu_u); - uio->uio_resid = pq->len; + uio->uio_resid = iv->iov_len; iv++; - if(sp->hdrDigest) + if(ISOK2DIG(sp->hdrDigest, pp)) pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0); if(pp->ahs_len) { - iv->iov_base = pp->ahs; + iv->iov_base = pp->ahs_addr; iv->iov_len = pp->ahs_len; + uio->uio_resid += iv->iov_len; iv++; - - if(sp->hdrDigest) - pq->pdu.hdr_dig = sp->hdrDigest(&pp->ahs, pp->ahs_len, pq->pdu.hdr_dig); + if(ISOK2DIG(sp->hdrDigest, pp)) + pp->hdr_dig = sp->hdrDigest(&pp->ahs_addr, pp->ahs_len, pp->hdr_dig); } - if(sp->hdrDigest) { - debug(2, "hdr_dig=%x", pq->pdu.hdr_dig); + if(ISOK2DIG(sp->hdrDigest, pp)) { + debug(3, "hdr_dig=%04x", htonl(pp->hdr_dig)); iv->iov_base = &pp->hdr_dig; iv->iov_len = sizeof(int); + uio->uio_resid += iv->iov_len ; iv++; } - if(pq->pdu.ds) { - iv->iov_base = pp->ds; + if(pq->pdu.ds_addr && pp->ds_len) { + iv->iov_base = pp->ds_addr; iv->iov_len = pp->ds_len; while(iv->iov_len & 03) // the specs say it must be int alligned iv->iov_len++; + uio->uio_resid += iv->iov_len ; iv++; + if(ISOK2DIG(sp->dataDigest, pp)) { + pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0); + iv->iov_base = &pp->ds_dig; + iv->iov_len = sizeof(pp->ds_dig); + uio->uio_resid += iv->iov_len ; + iv++; + } } - if(sp->dataDigest) { - pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0); - iv->iov_base = &pp->ds_dig; - iv->iov_len = sizeof(int); - iv++; - } - uio->uio_iovcnt = iv - pq->iov; - sdebug(5, "opcode=%x iovcnt=%d uio_resid=%d itt=%x", + uio->uio_iovcnt = iv - pq->iov; + sdebug(4, "pq->len=%d uio->uio_resid=%d uio->uio_iovcnt=%d", pq->len, + uio->uio_resid, + uio->uio_iovcnt); + + sdebug(4, "opcode=%x iovcnt=%d uio_resid=%d itt=%x", pp->ipdu.bhs.opcode, uio->uio_iovcnt, uio->uio_resid, ntohl(pp->ipdu.bhs.itt)); sdebug(5, "sp=%p sp->soc=%p uio=%p sp->td=%p", @@ -244,12 +259,12 @@ | XXX: untested code */ sdebug(1, "uio->uio_resid=%d uio->uio_iovcnt=%d", - uio->uio_resid, uio->uio_iovcnt); + uio->uio_resid, uio->uio_iovcnt); iv = uio->uio_iov; len -= uio->uio_resid; while(uio->uio_iovcnt > 0) { if(iv->iov_len > len) { - caddr_t bp = (caddr_t)iv->iov_base; + caddr_t bp = (caddr_t)iv->iov_base; iv->iov_len -= len; iv->iov_base = (void *)&bp[len]; @@ -265,7 +280,6 @@ if(error == 0) { sp->stats.nsent++; getbintime(&sp->stats.t_sent); - } return error; @@ -322,159 +336,197 @@ error = soreceive(sp->soc, NULL, uio, 0, 0, &flags); if(error) - debug(2, "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd", + debug(2, +#if __FreeBSD_version > 800000 + "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd", +#else + "error=%d so_error=%d uio->uio_resid=%d iov.iov_len=%zd", +#endif error, sp->soc->so_error, uio->uio_resid, iov->iov_len); if(!error && (uio->uio_resid > 0)) { error = EPIPE; // was EAGAIN - debug(2, "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd so_state=%x", + debug(2, +#if __FreeBSD_version > 800000 + "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd so_state=%x", +#else + "error=%d so_error=%d uio->uio_resid=%d iov.iov_len=%zd so_state=%x", +#endif error, sp->soc->so_error, uio->uio_resid, iov->iov_len, sp->soc->so_state); } - return error; } /* - | so_recv gets called when there is at least - | an iSCSI header in the queue + | so_recv gets called when + | an iSCSI header has been received. + | Note: the designers had no intentions + | in making programmer's life easy. */ static int so_recv(isc_session_t *sp, pduq_t *pq) { - struct socket *so = sp->soc; sn_t *sn = &sp->sn; struct uio *uio = &pq->uio; - pdu_t *pp; + pdu_t *pp = &pq->pdu; + bhs_t *bhs = &pp->ipdu.bhs; + struct iovec *iov = pq->iov; int error; - size_t n, len; - bhs_t *bhs; + u_int len; u_int max, exp; + int flags = MSG_WAITALL; debug_called(8); /* | now calculate how much data should be in the buffer - | NOTE: digest is not verified/calculated - yet */ - pp = &pq->pdu; - bhs = &pp->ipdu.bhs; - + uio->uio_iov = iov; + uio->uio_iovcnt = 0; len = 0; if(bhs->AHSLength) { + debug(2, "bhs->AHSLength=%d", bhs->AHSLength); pp->ahs_len = bhs->AHSLength * 4; len += pp->ahs_len; + pp->ahs_addr = malloc(pp->ahs_len, M_TEMP, M_WAITOK); // XXX: could get stuck here + iov->iov_base = pp->ahs_addr; + iov->iov_len = pp->ahs_len; + uio->uio_iovcnt++; + iov++; } - if(sp->hdrDigest) - len += 4; + if(ISOK2DIG(sp->hdrDigest, pp)) { + len += sizeof(pp->hdr_dig); + iov->iov_base = &pp->hdr_dig; + iov->iov_len = sizeof(pp->hdr_dig); + uio->uio_iovcnt++; + } + if(len) { + uio->uio_rw = UIO_READ; + uio->uio_segflg = UIO_SYSSPACE; + uio->uio_resid = len; + uio->uio_td = sp->td; // why ... + error = soreceive(sp->soc, NULL, uio, NULL, NULL, &flags); + //if(error == EAGAIN) + // XXX: this needs work! it hangs iscontrol + if(error || uio->uio_resid) { + debug(2, +#if __FreeBSD_version > 800000 + "len=%d error=%d uio->uio_resid=%zd", +#else + "len=%d error=%d uio->uio_resid=%d", +#endif + len, error, uio->uio_resid); + goto out; + } + if(ISOK2DIG(sp->hdrDigest, pp)) { + bhs_t *bhs; + u_int digest; + + bhs = (bhs_t *)&pp->ipdu; + digest = sp->hdrDigest(bhs, sizeof(bhs_t), 0); + if(pp->ahs_len) + digest = sp->hdrDigest(pp->ahs_addr, pp->ahs_len, digest); + if(pp->hdr_dig != digest) { + debug(2, "bad header digest: received=%x calculated=%x", pp->hdr_dig, digest); + // XXX: now what? + error = EIO; + goto out; + } + } + if(pp->ahs_len) { + debug(2, "ahs len=%x type=%x spec=%x", + pp->ahs_addr->len, pp->ahs_addr->type, pp->ahs_addr->spec); + // XXX: till I figure out what to do with this + free(pp->ahs_addr, M_TEMP); + } + pq->len += len; // XXX: who needs this? + bzero(uio, sizeof(struct uio)); + len = 0; + } + if(bhs->DSLength) { - n = bhs->DSLength; + len = bhs->DSLength; #if BYTE_ORDER == LITTLE_ENDIAN - pp->ds_len = ((n & 0x00ff0000) >> 16) - | (n & 0x0000ff00) - | ((n & 0x000000ff) << 16); -#else - pp->ds_len = n; + len = ((len & 0x00ff0000) >> 16) + | (len & 0x0000ff00) + | ((len & 0x000000ff) << 16); #endif - len += pp->ds_len; + pp->ds_len = len; + if((sp->opt.maxRecvDataSegmentLength > 0) && (len > sp->opt.maxRecvDataSegmentLength)) { + xdebug("impossible PDU length(%d) opt.maxRecvDataSegmentLength=%d", + len, sp->opt.maxRecvDataSegmentLength); + log(LOG_ERR, + "so_recv: impossible PDU length(%d) from iSCSI %s/%s\n", + len, sp->opt.targetAddress, sp->opt.targetName); + /* + | XXX: this will really screwup the stream. + | should clear up the buffer till a valid header + | is found, or just close connection ... + | should read the RFC. + */ + error = E2BIG; + goto out; + } while(len & 03) len++; - if(sp->dataDigest) + if(ISOK2DIG(sp->dataDigest, pp)) len += 4; - } - - if((sp->opt.maxRecvDataSegmentLength > 0) && (len > sp->opt.maxRecvDataSegmentLength)) { -#if 0 - xdebug("impossible PDU length(%d) opt.maxRecvDataSegmentLength=%d", - len, sp->opt.maxRecvDataSegmentLength); - // deep trouble here, probably all we can do is - // force a disconnect, XXX: check RFC ... - log(LOG_ERR, - "so_recv: impossible PDU length(%ld) from iSCSI %s/%s\n", - len, sp->opt.targetAddress, sp->opt.targetName); -#endif - /* - | XXX: this will really screwup the stream. - | should clear up the buffer till a valid header - | is found, or just close connection ... - | should read the RFC. - */ - error = E2BIG; - goto out; - } - if(len) { - int flags = MSG_WAITALL; - struct mbuf **mp; - - mp = &pq->mp; - uio->uio_resid = len; - uio->uio_td = curthread; // why ... - if(sp->douio) { - // it's more efficient to use mbufs -- why? - if(bhs->opcode == ISCSI_READ_DATA) { - pduq_t *opq; - - opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1); - if(opq != NULL) { - union ccb *ccb = opq->ccb; - struct ccb_scsiio *csio = &ccb->csio; - pdu_t *opp = &opq->pdu; - scsi_req_t *cmd = &opp->ipdu.scsi_req; - data_in_t *rcmd = &pq->pdu.ipdu.data_in; - bhs_t *bhp = &opp->ipdu.bhs; - int r; - - if(bhp->opcode == ISCSI_SCSI_CMD - && cmd->R - && (ntohl(cmd->edtlen) >= pq->pdu.ds_len)) { - struct iovec *iov = pq->iov; - iov->iov_base = csio->data_ptr + ntohl(rcmd->bo); - iov->iov_len = pq->pdu.ds_len; - - uio->uio_rw = UIO_READ; - uio->uio_segflg = UIO_SYSSPACE; - uio->uio_iov = iov; - uio->uio_iovcnt = 1; - if(len > pq->pdu.ds_len) { - pq->iov[1].iov_base = &r; - pq->iov[1].iov_len = len - pq->pdu.ds_len; - uio->uio_iovcnt++; - } - mp = NULL; - - sdebug(4, "uio_resid=0x%zx itt=0x%x bp=%p bo=%x len=%x/%x", - uio->uio_resid, - ntohl(pq->pdu.ipdu.bhs.itt), - csio->data_ptr, ntohl(rcmd->bo), ntohl(cmd->edtlen), pq->pdu.ds_len); - } - } - } - } - error = soreceive(so, NULL, uio, mp, NULL, &flags); + uio->uio_td = sp->td; // why ... + pq->len += len; // XXX: do we need this? + error = soreceive(sp->soc, NULL, uio, &pq->mp, NULL, &flags); //if(error == EAGAIN) // XXX: this needs work! it hangs iscontrol if(error || uio->uio_resid) goto out; + if(ISOK2DIG(sp->dataDigest, pp)) { + struct mbuf *m; + u_int digest, ds_len, cnt; + + // get the received digest + m_copydata(pq->mp, + len - sizeof(pp->ds_dig), + sizeof(pp->ds_dig), + (caddr_t)&pp->ds_dig); + // calculate all mbufs + digest = 0; + ds_len = len - sizeof(pp->ds_dig); + for(m = pq->mp; m != NULL; m = m->m_next) { + cnt = MIN(ds_len, m->m_len); + digest = sp->dataDigest(mtod(m, char *), cnt, digest); + ds_len -= cnt; + if(ds_len == 0) + break; + } + if(digest != pp->ds_dig) { + sdebug(1, "bad data digest: received=%x calculated=%x", pp->ds_dig, digest); + error = EIO; // XXX: find a better error + goto out; + } + KASSERT(ds_len == 0, ("ds_len not zero")); + } } - pq->len += len; sdebug(6, "len=%d] opcode=0x%x ahs_len=0x%x ds_len=0x%x", pq->len, bhs->opcode, pp->ahs_len, pp->ds_len); max = ntohl(bhs->MaxCmdSN); exp = ntohl(bhs->ExpStSN); - if(max < exp - 1 && max > exp - _MAXINCR) { sdebug(2, "bad cmd window size"); error = EIO; // XXX: for now; goto out; // error } - if(SNA_GT(max, sn->maxCmd)) sn->maxCmd = max; - if(SNA_GT(exp, sn->expCmd)) sn->expCmd = exp; + /* + | remove from the holding queue packets + | that have been acked and don't need + | further processing. + */ + i_acked_hld(sp, NULL); sp->cws = sn->maxCmd - sn->expCmd + 1; @@ -482,6 +534,10 @@ out: // XXX: need some work here + if(pp->ahs_len) { + // XXX: till I figure out what to do with this + free(pp->ahs_addr, M_TEMP); + } xdebug("have a problem, error=%d", error); pdu_free(sp->isc, pq); if(!error && uio->uio_resid > 0) @@ -510,8 +566,8 @@ */ pq = pdu_alloc(sp->isc, M_NOWAIT); if(pq == NULL) { // XXX: might cause a deadlock ... - debug(3, "out of pdus, wait"); - pq = pdu_alloc(sp->isc, M_NOWAIT); // OK to WAIT + debug(2, "out of pdus, wait"); + pq = pdu_alloc(sp->isc, M_WAITOK); // OK to WAIT } pq->pdu.ipdu.bhs = sp->bhs; pq->len = sizeof(bhs_t); // so far only the header was read @@ -536,7 +592,7 @@ | in packets from the target. */ static void -isc_soc(void *vp) +isc_in(void *vp) { isc_session_t *sp = (isc_session_t *)vp; struct socket *so = sp->soc; @@ -545,9 +601,6 @@ debug_called(8); sp->flags |= ISC_CON_RUNNING; - if(sp->cam_path) - ic_release(sp); - error = 0; while((sp->flags & (ISC_CON_RUN | ISC_LINK_UP)) == (ISC_CON_RUN | ISC_LINK_UP)) { // XXX: hunting ... @@ -559,7 +612,7 @@ if(error == 0) { mtx_lock(&sp->io_mtx); if(sp->flags & ISC_OWAITING) { - wakeup(&sp->flags); + wakeup(&sp->flags); } mtx_unlock(&sp->io_mtx); } else if(error == EPIPE) { @@ -594,8 +647,11 @@ mtx_unlock(&sp->io_mtx); sdebug(2, "dropped ISC_CON_RUNNING"); - +#if __FreeBSD_version >= 800000 kproc_exit(0); +#else + kthread_exit(0); +#endif } void @@ -621,7 +677,6 @@ } mtx_unlock(&sp->io_mtx); - if(sp->fp != NULL) fdrop(sp->fp, sp->td); fputsock(sp->soc); @@ -637,6 +692,10 @@ debug_called(8); sp->flags |= ISC_CON_RUN | ISC_LINK_UP; - - kproc_create(isc_soc, sp, &sp->soc_proc, 0, 0, "iscsi%d", sp->sid); +#if __FreeBSD_version >= 800000 + kproc_create +#else + kthread_create +#endif + (isc_in, sp, &sp->soc_proc, 0, 0, "isc_in %d", sp->sid); } Index: sys/dev/iscsi/initiator/iscsi_subr.c =================================================================== --- sys/dev/iscsi/initiator/iscsi_subr.c (revision 210555) +++ sys/dev/iscsi/initiator/iscsi_subr.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ * */ /* - | $Id: iscsi_subr.c,v 1.17 2006/11/26 14:50:43 danny Exp danny $ + | $Id: iscsi_subr.c 743 2009-08-08 10:54:53Z danny $ */ #include @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -122,7 +123,7 @@ bs = MIN(bs, bleft); wpq->pdu.ds_len = bs; - wpq->pdu.ds = bp; + wpq->pdu.ds_addr = bp; error = isc_qout(sp, wpq); sdebug(6, "bs=%x bo=%x bp=%p dsn=%x error=%d", bs, bo, bp, dsn, error); @@ -188,16 +189,16 @@ | Some information is from SAM draft. */ static void -_scsi_done(struct isc_softc *isp, u_int response, u_int status, union ccb *ccb, pduq_t *pq) +_scsi_done(isc_session_t *sp, u_int response, u_int status, union ccb *ccb, pduq_t *pq) { struct ccb_hdr *ccb_h = &ccb->ccb_h; debug_called(8); if(status || response) { - debug(3, "response=%x status=%x ccb=%p pq=%p", response, status, ccb, pq); + sdebug(3, "response=%x status=%x ccb=%p pq=%p", response, status, ccb, pq); if(pq != NULL) - debug(3, "mp=%p buf=%p len=%d", pq->mp, pq->buf, pq->len); + sdebug(3, "mp=%p buf=%p len=%d", pq->mp, pq->buf, pq->len); } ccb_h->status = 0; switch(response) { @@ -241,9 +242,9 @@ ccb_h->status = CAM_REQ_CMP_ERR; //CAM_REQ_ABORTED; break; } - debug(5, "ccb_h->status=%x", ccb_h->status); + sdebug(5, "ccb_h->status=%x", ccb_h->status); - XPT_DONE(isp, ccb); + XPT_DONE(sp, ccb); } /* @@ -256,16 +257,17 @@ u_int i, n, last; debug_called(8); - last = -1; - i = 0; + i = last = 0; sp->flags |= ISC_HOLD; while((pq = i_dqueue_hld(sp)) != NULL) { i++; - _scsi_done(sp->isc, 0, 0x28, pq->ccb, NULL); - n = ntohl(pq->pdu.ipdu.bhs.CmdSN); - if(last > n) - last = n; - sdebug(2, "last=%x n=%x", last, n); + if(pq->ccb != NULL) { + _scsi_done(sp, 0, 0x28, pq->ccb, NULL); + n = ntohl(pq->pdu.ipdu.bhs.CmdSN); + if(last==0 || (last > n)) + last = n; + sdebug(2, "last=%x n=%x", last, n); + } pdu_free(sp->isc, pq); } sp->flags &= ~ISC_HOLD; @@ -316,14 +318,22 @@ TAILQ_FOREACH_SAFE(pq, &sp->hld, pq_link, pqtmp) { sdebug(3, "hld pq=%p", pq); if(pq->ccb) - _scsi_done(sp->isc, 1, 0x40, pq->ccb, NULL); + _scsi_done(sp, 1, 0x40, pq->ccb, NULL); TAILQ_REMOVE(&sp->hld, pq, pq_link); + if(pq->buf) { + free(pq->buf, M_ISCSIBUF); + pq->buf = NULL; + } pdu_free(sp->isc, pq); } while((pq = i_dqueue_snd(sp, BIT(0)|BIT(1)|BIT(2))) != NULL) { sdebug(3, "pq=%p", pq); if(pq->ccb) - _scsi_done(sp->isc, 1, 0x40, pq->ccb, NULL); + _scsi_done(sp, 1, 0x40, pq->ccb, NULL); + if(pq->buf) { + free(pq->buf, M_ISCSIBUF); + pq->buf = NULL; + } pdu_free(sp->isc, pq); } @@ -338,7 +348,7 @@ debug_called(8); - _scsi_done(sp->isc, cmd->response, cmd->status, opq->ccb, pq); + _scsi_done(sp, cmd->response, cmd->status, opq->ccb, pq); pdu_free(sp->isc, opq); } @@ -394,7 +404,7 @@ debug_called(8); //XXX: check RFC 10.17.1 (page 176) ccb->ccb_h.status = CAM_REQ_ABORTED; - XPT_DONE(sp->isc, ccb); + XPT_DONE(sp, ccb); pdu_free(sp->isc, opq); } @@ -405,10 +415,8 @@ static int dwl(isc_session_t *sp, int lun, u_char *lp) { - int i; - debug_called(8); - + sdebug(4, "lun=%d", lun); /* | mapping LUN to iSCSI LUN | check the SAM-2 specs @@ -429,14 +437,6 @@ return -1; } - for(i = 0; i < sp->target_nluns; i++) - if(sp->target_lun[i] == lun) - return 0; - if(sp->target_nluns < ISCSI_MAX_LUNS) - sp->target_lun[sp->target_nluns++] = lun; - - sdebug(3, "nluns=%d lun=%d", sp->target_nluns, lun); - return 0; } @@ -446,8 +446,7 @@ int scsi_encap(struct cam_sim *sim, union ccb *ccb) { - struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim); - isc_session_t *sp; + isc_session_t *sp = cam_sim_softc(sim); struct ccb_scsiio *csio = &ccb->csio; struct ccb_hdr *ccb_h = &ccb->ccb_h; pduq_t *pq; @@ -458,33 +457,19 @@ debug(4, "ccb->sp=%p", ccb_h->spriv_ptr0); sp = ccb_h->spriv_ptr0; - if((pq = pdu_alloc(isp, M_NOWAIT)) == NULL) { + if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) { debug(2, "ccb->sp=%p", ccb_h->spriv_ptr0); sdebug(1, "pdu_alloc failed sc->npdu_max=%d npdu_alloc=%d", sp->isc->npdu_max, sp->isc->npdu_alloc); while((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) { - sdebug(3, "waiting..."); + sdebug(2, "waiting..."); #if __FreeBSD_version >= 700000 pause("isc_encap", 5*hz); #else tsleep(sp->isc, 0, "isc_encap", 5*hz); #endif } -#if 0 - sdebug(3, "freezing"); - ccb->ccb_h.status = CAM_REQUEUE_REQ; - ic_freeze(sp); - return 0; -#endif } - -#if 0 - if((sp->flags & ISC_FFPHASE) == 0) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; // CAM_NO_NEXUS; - sdebug(3, "no active session with target %d", ccb_h->target_id); - goto bad; - } -#endif cmd = &pq->pdu.ipdu.scsi_req; cmd->opcode = ISCSI_SCSI_CMD; cmd->F = 1; @@ -493,8 +478,8 @@ */ switch(csio->tag_action) { case MSG_SIMPLE_Q_TAG: cmd->attr = iSCSI_TASK_SIMPLE; break; - case MSG_HEAD_OF_Q_TAG: cmd->attr = iSCSI_TASK_ORDER; break; - case MSG_ORDERED_Q_TAG: cmd->attr = iSCSI_TASK_HOFQ; break; + case MSG_HEAD_OF_Q_TAG: cmd->attr = iSCSI_TASK_HOFQ; break; + case MSG_ORDERED_Q_TAG: cmd->attr = iSCSI_TASK_ORDER; break; case MSG_ACA_TASK: cmd->attr = iSCSI_TASK_ACA; break; } @@ -532,7 +517,8 @@ return 1; invalid: ccb->ccb_h.status = CAM_REQ_INVALID; - pdu_free(isp, pq); + pdu_free(sp->isc, pq); + return 0; } @@ -573,16 +559,16 @@ csio->data_ptr, bp? mtod(pq->mp, caddr_t): 0, ntohl(cmd->edtlen), pq->pdu.ds_len, pq->mp); if(ntohl(cmd->edtlen) >= pq->pdu.ds_len) { - int offset, len = pq->pdu.ds_len; + int offset, len = pq->pdu.ds_len; if(pq->mp != NULL) { - caddr_t dp; + caddr_t dp; - offset = ntohl(rcmd->bo); - dp = csio->data_ptr + offset; - i_mbufcopy(pq->mp, dp, len); + offset = ntohl(rcmd->bo); + dp = csio->data_ptr + offset; + i_mbufcopy(pq->mp, dp, len); + } } - } else { xdebug("edtlen=%d < ds_len=%d", ntohl(cmd->edtlen), pq->pdu.ds_len); @@ -592,7 +578,7 @@ /* | contains also the SCSI Status */ - _scsi_done(sp->isc, 0, rcmd->status, opq->ccb, NULL); + _scsi_done(sp, 0, rcmd->status, opq->ccb, NULL); return 0; } else return 1; Index: sys/dev/iscsi/initiator/iscsivar.h =================================================================== --- sys/dev/iscsi/initiator/iscsivar.h (revision 210555) +++ sys/dev/iscsi/initiator/iscsivar.h (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,9 +25,18 @@ * * $FreeBSD$ */ + /* - | $Id: iscsivar.h,v 1.30 2007/04/22 10:12:11 danny Exp danny $ + | $Id: iscsivar.h 743 2009-08-08 10:54:53Z danny $ */ +#define ISCSI_MAX_LUNS 128 // don't touch this +#if ISCSI_MAX_LUNS > 8 +/* + | for this to work + | sysctl kern.cam.cam_srch_hi=1 + */ +#endif + #ifndef ISCSI_INITIATOR_DEBUG #define ISCSI_INITIATOR_DEBUG 1 #endif @@ -48,13 +57,17 @@ #define xdebug(fmt, args...) printf(">>> %s: " fmt "\n", __func__ , ##args) -#define MAX_SESSIONS ISCSI_MAX_TARGETS +#define MAX_SESSIONS ISCSI_MAX_TARGETS +#define MAX_PDUS (MAX_SESSIONS*256) // XXX: at the moment this is arbitrary typedef uint32_t digest_t(const void *, int len, uint32_t ocrc); MALLOC_DECLARE(M_ISCSI); +MALLOC_DECLARE(M_ISCSIBUF); MALLOC_DECLARE(M_PDU); +#define ISOK2DIG(dig, pp) ((dig != NULL) && ((pp->ipdu.bhs.opcode & 0x1f) != ISCSI_LOGIN_CMD)) + #ifndef BIT #define BIT(n) (1 <<(n)) #endif @@ -69,16 +82,16 @@ #define ISC_OQNOTEMPTY BIT(6) #define ISC_OWAITING BIT(7) #define ISC_FFPHASE BIT(8) -#define ISC_FFPWAIT BIT(9) -#define ISC_MEMWAIT BIT(10) -#define ISC_SIGNALED BIT(11) -#define ISC_FROZEN BIT(12) -#define ISC_STALLED BIT(13) +#define ISC_CAMDEVS BIT(9) +#define ISC_SCANWAIT BIT(10) -#define ISC_HOLD BIT(14) -#define ISC_HOLDED BIT(15) +#define ISC_MEMWAIT BIT(11) +#define ISC_SIGNALED BIT(12) +#define ISC_HOLD BIT(15) +#define ISC_HOLDED BIT(16) + #define ISC_SHUTDOWN BIT(31) /* @@ -116,9 +129,7 @@ struct proc *proc; // the userland process int signal; - struct proc *soc_proc; - struct proc *stp; // the sm thread struct isc_softc *isc; @@ -127,16 +138,13 @@ digest_t *dataDigest; // the digest alg. if any int sid; // Session ID - int targetid; -// int cid; // Connection ID -// int tsih; // target session identifier handle sn_t sn; // sequence number stuff; int cws; // current window size int target_nluns; // this and target_lun are // hopefully temporal till I // figure out a better way. - lun_id_t target_lun[ISCSI_MAX_LUNS]; + int target_lun[ISCSI_MAX_LUNS/(sizeof(int)*8) + 1]; struct mtx rsp_mtx; struct mtx rsv_mtx; @@ -150,17 +158,19 @@ queue_t wsnd; queue_t hld; - /* - | negotiable values - */ - isc_opt_t opt; + isc_opt_t opt; // negotiable values struct i_stats stats; - struct cam_path *cam_path; bhs_t bhs; struct uio uio; struct iovec iov; /* + | cam stuff + */ + struct cam_sim *cam_sim; + struct cam_path *cam_path; + struct mtx cam_mtx; + /* | sysctl stuff */ struct sysctl_ctx_list clist; @@ -180,34 +190,30 @@ struct iovec iov[5]; // XXX: careful ... struct mbuf *mp; struct bintime ts; - queue_t *pduq; + queue_t *pduq; } pduq_t; - +/* + */ struct isc_softc { - //int state; + struct mtx isc_mtx; + TAILQ_HEAD(,isc_session) isc_sess; + int nsess; struct cdev *dev; - eventhandler_tag eh; char isid[6]; // Initiator Session ID (48 bits) - struct mtx mtx; + struct unrhdr *unit; + struct sx unit_sx; - int nsess; - TAILQ_HEAD(,isc_session) isc_sess; - isc_session_t *sessions[MAX_SESSIONS]; + struct mtx pdu_mtx; + uma_zone_t pdu_zone; // pool of free pdu's + TAILQ_HEAD(,pduq) freepdu; - struct mtx pdu_mtx; #ifdef ISCSI_INITIATOR_DEBUG - int npdu_alloc, npdu_max; // for instrumentation + int npdu_alloc, npdu_max; // for instrumentation #endif -#define MAX_PDUS (MAX_SESSIONS*256) // XXX: at the moment this is arbitrary - uma_zone_t pdu_zone; // pool of free pdu's - TAILQ_HEAD(,pduq) freepdu; +#ifdef DO_EVENTHANDLER + eventhandler_tag eh; +#endif /* - | cam stuff - */ - struct cam_sim *cam_sim; - struct cam_path *cam_path; - struct mtx cam_mtx; - /* | sysctl stuff */ struct sysctl_ctx_list clist; @@ -231,14 +237,14 @@ int i_setopt(isc_session_t *sp, isc_opt_t *opt); void i_freeopt(isc_opt_t *opt); -int ic_init(struct isc_softc *sc); -void ic_destroy(struct isc_softc *sc); -int ic_fullfeature(struct cdev *dev); +int ic_init(isc_session_t *sp); +void ic_destroy(isc_session_t *sp); void ic_lost_target(isc_session_t *sp, int target); int ic_getCamVals(isc_session_t *sp, iscsi_cam_t *cp); void ism_recv(isc_session_t *sp, pduq_t *pq); int ism_start(isc_session_t *sp); +void ism_restart(isc_session_t *sp); void ism_stop(isc_session_t *sp); int scsi_encap(struct cam_sim *sim, union ccb *ccb); @@ -250,9 +256,6 @@ void iscsi_cleanup(isc_session_t *sp); int iscsi_requeue(isc_session_t *sp); -void ic_freeze(isc_session_t *sp); -void ic_release(isc_session_t *sp); - // Serial Number Arithmetic #define _MAXINCR 0x7FFFFFFF // 2 ^ 31 - 1 #define SNA_GT(i1, i2) ((i1 != i2) && (\ @@ -269,7 +272,7 @@ #define CAM_ULOCK(arg) static __inline void -XPT_DONE(struct isc_softc *isp, union ccb *ccb) +XPT_DONE(isc_session_t *sp, union ccb *ccb) { mtx_lock(&Giant); xpt_done(ccb); @@ -280,11 +283,11 @@ #define CAM_UNLOCK(arg) mtx_unlock(&arg->cam_mtx) static __inline void -XPT_DONE(struct isc_softc *isp, union ccb *ccb) +XPT_DONE(isc_session_t *sp, union ccb *ccb) { - CAM_LOCK(isp); + CAM_LOCK(sp); xpt_done(ccb); - CAM_UNLOCK(isp); + CAM_UNLOCK(sp); } #else //__FreeBSD_version >= 600000 @@ -332,7 +335,7 @@ m_freem(pq->mp); #ifdef NO_USE_MBUF if(pq->buf != NULL) - free(pq->buf, M_ISCSI); + free(pq->buf, M_ISCSIBUF); #endif mtx_lock(&isc->pdu_mtx); TAILQ_INSERT_TAIL(&isc->freepdu, pq, pq_link); @@ -565,6 +568,27 @@ } static __inline void +i_acked_hld(isc_session_t *sp, pdu_t *op) +{ + pduq_t *pq, *tmp; + u_int exp = sp->sn.expCmd; + + pq = NULL; + mtx_lock(&sp->hld_mtx); + TAILQ_FOREACH_SAFE(pq, &sp->hld, pq_link, tmp) { + if((op && op->ipdu.bhs.itt == pq->pdu.ipdu.bhs.itt) + || (pq->ccb == NULL + && (pq->pdu.ipdu.bhs.opcode != ISCSI_WRITE_DATA) + && SNA_GT(exp, ntohl(pq->pdu.ipdu.bhs.ExpStSN)))) { + sp->stats.nhld--; + TAILQ_REMOVE(&sp->hld, pq, pq_link); + pdu_free(sp->isc, pq); + } + } + mtx_unlock(&sp->hld_mtx); +} + +static __inline void i_mbufcopy(struct mbuf *mp, caddr_t dp, int len) { struct mbuf *m; Index: sys/dev/iscsi/initiator/isc_subr.c =================================================================== --- sys/dev/iscsi/initiator/isc_subr.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_subr.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ */ /* | iSCSI - | $Id: isc_subr.c,v 1.20 2006/12/01 09:10:17 danny Exp danny $ + | $Id: isc_subr.c 560 2009-05-07 07:37:49Z danny $ */ #include @@ -58,29 +58,121 @@ #include #include +MALLOC_DEFINE(M_ISC, "iSC", "iSCSI driver options"); + static char * i_strdupin(char *s, size_t maxlen) { size_t len; char *p, *q; - p = malloc(maxlen, M_ISCSI, M_WAITOK); + p = malloc(maxlen, M_ISC, M_WAITOK); if(copyinstr(s, p, maxlen, &len)) { - free(p, M_ISCSI); + free(p, M_ISC); return NULL; } - q = malloc(len, M_ISCSI, M_WAITOK); + q = malloc(len, M_ISC, M_WAITOK); bcopy(p, q, len); - free(p, M_ISCSI); + free(p, M_ISC); return q; } +/*****************************************************************/ +/* */ +/* CRC LOOKUP TABLE */ +/* ================ */ +/* The following CRC lookup table was generated automagically */ +/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ +/* Program V1.0 using the following model parameters: */ +/* */ +/* Width : 4 bytes. */ +/* Poly : 0x1EDC6F41L */ +/* Reverse : TRUE. */ +/* */ +/* For more information on the Rocksoft^tm Model CRC Algorithm, */ +/* see the document titled "A Painless Guide to CRC Error */ +/* Detection Algorithms" by Ross Williams */ +/* (ross@guest.adelaide.edu.au.). This document is likely to be */ +/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/*****************************************************************/ + +static uint32_t crc32Table[256] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L +}; + static uint32_t i_crc32c(const void *buf, size_t size, uint32_t crc) { + const uint8_t *p = buf; + crc = crc ^ 0xffffffff; - crc = calculate_crc32c(crc, buf, size); + while (size--) + crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8); crc = crc ^ 0xffffffff; return crc; } @@ -98,50 +190,51 @@ if(opt->maxXmitDataSegmentLength > 0) { // danny's RFC sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength; - sdebug(2, "maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength); + sdebug(2, "opt.maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength); } if(opt->maxBurstLength != 0) { sp->opt.maxBurstLength = opt->maxBurstLength; - sdebug(2, "maxBurstLength=%d", sp->opt.maxBurstLength); + sdebug(2, "opt.maxBurstLength=%d", sp->opt.maxBurstLength); } if(opt->targetAddress != NULL) { if(sp->opt.targetAddress != NULL) - free(sp->opt.targetAddress, M_ISCSI); + free(sp->opt.targetAddress, M_ISC); sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128); - sdebug(4, "opt.targetAddress='%s'", sp->opt.targetAddress); + sdebug(2, "opt.targetAddress='%s'", sp->opt.targetAddress); } if(opt->targetName != NULL) { if(sp->opt.targetName != NULL) - free(sp->opt.targetName, M_ISCSI); + free(sp->opt.targetName, M_ISC); sp->opt.targetName = i_strdupin(opt->targetName, 128); - sdebug(4, "opt.targetName='%s'", sp->opt.targetName); + sdebug(2, "opt.targetName='%s'", sp->opt.targetName); } if(opt->initiatorName != NULL) { if(sp->opt.initiatorName != NULL) - free(sp->opt.initiatorName, M_ISCSI); + free(sp->opt.initiatorName, M_ISC); sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128); - sdebug(4, "opt.initiatorName='%s'", sp->opt.initiatorName); + sdebug(2, "opt.initiatorName='%s'", sp->opt.initiatorName); } if(opt->maxluns > 0) { if(opt->maxluns > ISCSI_MAX_LUNS) sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ... sp->opt.maxluns = opt->maxluns; - sdebug(4, "opt.maxluns=%d", sp->opt.maxluns); + sdebug(2, "opt.maxluns=%d", sp->opt.maxluns); } if(opt->headerDigest != NULL) { sdebug(2, "opt.headerDigest='%s'", opt->headerDigest); if(strcmp(opt->headerDigest, "CRC32C") == 0) { sp->hdrDigest = (digest_t *)i_crc32c; - sdebug(2, "headerDigest set"); + sdebug(2, "opt.headerDigest set"); } } if(opt->dataDigest != NULL) { + sdebug(2, "opt.dataDigest='%s'", opt->headerDigest); if(strcmp(opt->dataDigest, "CRC32C") == 0) { sp->dataDigest = (digest_t *)i_crc32c; - sdebug(2, "dataDigest set"); + sdebug(2, "opt.dataDigest set"); } } @@ -151,16 +244,18 @@ void i_freeopt(isc_opt_t *opt) { + debug_called(8); + if(opt->targetAddress != NULL) { - free(opt->targetAddress, M_ISCSI); + free(opt->targetAddress, M_ISC); opt->targetAddress = NULL; } if(opt->targetName != NULL) { - free(opt->targetName, M_ISCSI); + free(opt->targetName, M_ISC); opt->targetName = NULL; } if(opt->initiatorName != NULL) { - free(opt->initiatorName, M_ISCSI); + free(opt->initiatorName, M_ISC); opt->initiatorName = NULL; } } Index: sys/dev/iscsi/initiator/iscsi.c =================================================================== --- sys/dev/iscsi/initiator/iscsi.c (revision 210555) +++ sys/dev/iscsi/initiator/iscsi.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,8 +25,7 @@ * */ /* - | iSCSI - | $Id: iscsi.c,v 1.35 2007/04/22 08:58:29 danny Exp danny $ + | $Id: iscsi.c 752 2009-08-20 11:23:28Z danny $ */ #include @@ -56,15 +55,17 @@ #include #include #include +#include #include #include +static char *iscsi_driver_version = "2.2.4.2"; -static char *iscsi_driver_version = "2.1.0"; +static struct isc_softc *isc; -static struct isc_softc isc; - MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI driver"); +MALLOC_DEFINE(M_ISCSIBUF, "iSCbuf", "iSCSI buffers"); +MALLOC_DEFINE(M_TMP, "iSCtmp", "iSCSI tmp"); #ifdef ISCSI_INITIATOR_DEBUG int iscsi_debug = ISCSI_INITIATOR_DEBUG; @@ -74,6 +75,12 @@ struct mtx iscsi_dbg_mtx; #endif +static int max_sessions = MAX_SESSIONS; +SYSCTL_INT(_net, OID_AUTO, iscsi_initiator_max_sessions, CTLFLAG_RDTUN, &max_sessions, MAX_SESSIONS, + "Max sessions allowed"); +static int max_pdus = MAX_PDUS; +SYSCTL_INT(_net, OID_AUTO, iscsi_initiator_max_pdus, CTLFLAG_RDTUN, &max_pdus, MAX_PDUS, + "Max pdu pool"); static char isid[6+1] = { 0x80, @@ -91,6 +98,7 @@ static int i_send(struct cdev *dev, caddr_t arg, struct thread *td); static int i_recv(struct cdev *dev, caddr_t arg, struct thread *td); static int i_setsoc(isc_session_t *sp, int fd, struct thread *td); +static int i_fullfeature(struct cdev *dev, int flag); static d_open_t iscsi_open; static d_close_t iscsi_close; @@ -117,39 +125,28 @@ debug(7, "dev=%d", dev2unit(dev)); - if(dev2unit(dev) > MAX_SESSIONS) { + if(dev2unit(dev) > max_sessions) { // should not happen return ENODEV; } - if(dev2unit(dev) == MAX_SESSIONS) { -#if 1 - struct isc_softc *sc = (struct isc_softc *)dev->si_drv1; - - // this should be in iscsi_start - if(sc->cam_sim == NULL) - ic_init(sc); -#endif - } return 0; } static int iscsi_close(struct cdev *dev, int flag, int otyp, struct thread *td) { - struct isc *sc; isc_session_t *sp; debug_called(8); - debug(3, "flag=%x", flag); + debug(3, "session=%d flag=%x", dev2unit(dev), flag); - sc = (struct isc *)dev->si_drv1; - if(dev2unit(dev) == MAX_SESSIONS) { + if(dev2unit(dev) == max_sessions) { return 0; } - sp = (isc_session_t *)dev->si_drv2; + sp = dev->si_drv2; if(sp != NULL) { - sdebug(2, "session=%d flags=%x", dev2unit(dev), sp->flags ); + sdebug(3, "sp->flags=%x", sp->flags ); /* | if still in full phase, this probably means | that something went realy bad. @@ -170,19 +167,19 @@ static int iscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, struct thread *td) { - struct isc *sc; + struct isc_softc *sc; isc_session_t *sp; isc_opt_t *opt; int error; - sc = (struct isc *)dev->si_drv1; debug_called(8); error = 0; - if(dev2unit(dev) == MAX_SESSIONS) { + if(dev2unit(dev) == max_sessions) { /* | non Session commands */ + sc = dev->si_drv1; if(sc == NULL) return ENXIO; @@ -190,18 +187,17 @@ case ISCSISETSES: error = i_create_session(dev, (int *)arg); if(error == 0) - - break; + break; default: - error = ENXIO; // XXX: + error = ENXIO; } return error; } - sp = (isc_session_t *)dev->si_drv2; /* | session commands */ + sp = dev->si_drv2; if(sp == NULL) return ENXIO; @@ -230,7 +226,7 @@ break; case ISCSISTART: - error = sp->soc == NULL? ENOTCONN: ism_fullfeature(dev, 1); + error = sp->soc == NULL? ENOTCONN: i_fullfeature(dev, 1); if(error == 0) { sp->proc = td->td_proc; SYSCTL_ADD_UINT(&sp->clist, @@ -243,11 +239,11 @@ break; case ISCSIRESTART: - error = sp->soc == NULL? ENOTCONN: ism_fullfeature(dev, 2); + error = sp->soc == NULL? ENOTCONN: i_fullfeature(dev, 2); break; case ISCSISTOP: - error = ism_fullfeature(dev, 0); + error = i_fullfeature(dev, 0); break; case ISCSISIGNAL: { @@ -283,9 +279,9 @@ pduq_t *pq; char buf[1024]; - sc = (struct isc_softc *)dev->si_drv1; - sp = (isc_session_t *)dev->si_drv2; - if(dev2unit(dev) == MAX_SESSIONS) { + sc = dev->si_drv1; + sp = dev->si_drv2; + if(dev2unit(dev) == max_sessions) { sprintf(buf, "/----- Session ------/\n"); uiomove(buf, strlen(buf), uio); int i = 0; @@ -310,10 +306,11 @@ int i = 0; struct socket *so = sp->soc; #define pukeit(i, pq) do {\ - sprintf(buf, "%03d] %06x %02x %x %ld %jd\n",\ - i, ntohl( pq->pdu.ipdu.bhs.CmdSN), \ + sprintf(buf, "%03d] %06x %02x %06x %06x %zd\n",\ + i, ntohl(pq->pdu.ipdu.bhs.CmdSN),\ pq->pdu.ipdu.bhs.opcode, ntohl(pq->pdu.ipdu.bhs.itt),\ - (long)pq->ts.sec, pq->ts.frac);\ + ntohl(pq->pdu.ipdu.bhs.ExpStSN),\ + pq->ts.sec);\ } while(0) sprintf(buf, "%d/%d /---- hld -----/\n", sp->stats.nhld, sp->stats.max_hld); @@ -418,8 +415,7 @@ static int i_send(struct cdev *dev, caddr_t arg, struct thread *td) { - isc_session_t *sp = (isc_session_t *)dev->si_drv2; - struct isc_softc *sc = (struct isc_softc *)dev->si_drv1; + isc_session_t *sp = dev->si_drv2; caddr_t bp; pduq_t *pq; pdu_t *pp; @@ -430,38 +426,46 @@ if(sp->soc == NULL) return ENOTCONN; - if((pq = pdu_alloc(sc, M_NOWAIT)) == NULL) + if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) return EAGAIN; pp = &pq->pdu; pq->pdu = *(pdu_t *)arg; if((error = i_prepPDU(sp, pq)) != 0) goto out; - sdebug(3, "len=%d ahs_len=%d ds_len=%d", pq->len, pp->ahs_len, pp->ds_len); - - pq->buf = bp = malloc(pq->len - sizeof(union ipdu_u), M_ISCSI, M_NOWAIT); - if(pq->buf == NULL) { - error = EAGAIN; - goto out; + bp = NULL; + if((pq->len - sizeof(union ipdu_u)) > 0) { + pq->buf = bp = malloc(pq->len - sizeof(union ipdu_u), M_ISCSIBUF, M_NOWAIT); + if(pq->buf == NULL) { + error = EAGAIN; + goto out; + } } + else + pq->buf = NULL; // just in case? + + sdebug(2, "len=%d ahs_len=%d ds_len=%d buf=%zu@%p", + pq->len, pp->ahs_len, pp->ds_len, pq->len - sizeof(union ipdu_u), bp); + if(pp->ahs_len) { + // XXX: never tested, looks suspicious n = pp->ahs_len; - error = copyin(pp->ahs, bp, n); + error = copyin(pp->ahs_addr, bp, n); if(error != 0) { sdebug(3, "copyin ahs: error=%d", error); goto out; } - pp->ahs = (ahs_t *)bp; + pp->ahs_addr = (ahs_t *)bp; bp += n; } if(pp->ds_len) { n = pp->ds_len; - error = copyin(pp->ds, bp, n); + error = copyin(pp->ds_addr, bp, n); if(error != 0) { sdebug(3, "copyin ds: error=%d", error); goto out; } - pp->ds = bp; + pp->ds_addr = bp; bp += n; while(n & 03) { n++; @@ -470,24 +474,19 @@ } error = isc_qout(sp, pq); -#if 1 if(error == 0) wakeup(&sp->flags); // XXX: to 'push' proc_out ... -#endif out: if(error) - pdu_free(sc, pq); + pdu_free(sp->isc, pq); return error; } -/* - | NOTE: must calculate digest if requiered. - */ static int i_recv(struct cdev *dev, caddr_t arg, struct thread *td) { - isc_session_t *sp = (isc_session_t *)dev->si_drv2; + isc_session_t *sp = dev->si_drv2; pduq_t *pq; pdu_t *pp, *up; caddr_t bp; @@ -501,7 +500,6 @@ if(sp->soc == NULL) return ENOTCONN; - sdebug(3, ""); cnt = 6; // XXX: maybe the user can request a time out? mtx_lock(&sp->rsp_mtx); while((pq = TAILQ_FIRST(&sp->rsp)) == NULL) { @@ -514,7 +512,7 @@ } mtx_unlock(&sp->rsp_mtx); - sdebug(4, "cnt=%d", cnt); + sdebug(6, "cnt=%d", cnt); if(pq == NULL) { error = ENOTCONN; @@ -536,19 +534,15 @@ len = 0; if(pp->ahs_len) { len += pp->ahs_len; - if(sp->hdrDigest) - len += 4; } if(pp->ds_len) { len += pp->ds_len; - if(sp->hdrDigest) - len += 4; } mustfree = 0; if(len > pq->mp->m_len) { mustfree++; - bp = malloc(len, M_ISCSI, M_WAITOK); + bp = malloc(len, M_TMP, M_WAITOK); sdebug(4, "need mbufcopy: %d", len); i_mbufcopy(pq->mp, bp, len); } @@ -557,28 +551,24 @@ if(pp->ahs_len) { need = pp->ahs_len; - if(sp->hdrDigest) - need += 4; n = MIN(up->ahs_size, need); - error = copyout(bp, (caddr_t)up->ahs, n); + error = copyout(bp, (caddr_t)up->ahs_addr, n); up->ahs_len = n; bp += need; } if(!error && pp->ds_len) { need = pp->ds_len; - if(sp->hdrDigest) - need += 4; if((have = up->ds_size) == 0) { have = up->ahs_size - n; - up->ds = (caddr_t)up->ahs + n; + up->ds_addr = (caddr_t)up->ahs_addr + n; } n = MIN(have, need); - error = copyout(bp, (caddr_t)up->ds, n); + error = copyout(bp, (caddr_t)up->ds_addr, n); up->ds_len = n; } if(mustfree) - free(bp, M_ISCSI); + free(bp, M_TMP); } sdebug(6, "len=%d ahs_len=%d ds_len=%d", pq->len, pp->ahs_len, pp->ds_len); @@ -589,33 +579,57 @@ } static int +i_fullfeature(struct cdev *dev, int flag) +{ + isc_session_t *sp = dev->si_drv2; + int error; + + sdebug(2, "flag=%d", flag); + + error = 0; + switch(flag) { + case 0: // stop + sp->flags &= ~ISC_FFPHASE; + break; + case 1: // start + sp->flags |= ISC_FFPHASE; + error = ic_init(sp); + break; + case 2: // restart + sp->flags |= ISC_FFPHASE; + ism_restart(sp); + break; + } + return error; +} + +static int i_create_session(struct cdev *dev, int *ndev) { - struct isc_softc *sc = (struct isc_softc *)dev->si_drv1; + struct isc_softc *sc = dev->si_drv1; isc_session_t *sp; int error, n; debug_called(8); - sp = (isc_session_t *)malloc(sizeof *sp, M_ISCSI, M_WAITOK | M_ZERO); + + sp = malloc(sizeof(isc_session_t), M_ISCSI, M_WAITOK | M_ZERO); if(sp == NULL) return ENOMEM; - mtx_lock(&sc->mtx); - /* - | search for the lowest unused sid - */ - for(n = 0; n < MAX_SESSIONS; n++) - if(sc->sessions[n] == NULL) - break; - if(n == MAX_SESSIONS) { - mtx_unlock(&sc->mtx); + + sx_xlock(&sc->unit_sx); + if((n = alloc_unr(sc->unit)) < 0) { + sx_unlock(&sc->unit_sx); free(sp, M_ISCSI); + xdebug("too many sessions!"); return EPERM; } + sx_unlock(&sc->unit_sx); + + mtx_lock(&sc->isc_mtx); TAILQ_INSERT_TAIL(&sc->isc_sess, sp, sp_link); - sc->nsess++; - mtx_unlock(&sc->mtx); + isc->nsess++; + mtx_unlock(&sc->isc_mtx); - sc->sessions[n] = sp; sp->dev = make_dev(&iscsi_cdevsw, n, UID_ROOT, GID_WHEEL, 0600, "iscsi%d", n); *ndev = sp->sid = n; sp->isc = sc; @@ -624,10 +638,9 @@ sp->opt.maxRecvDataSegmentLength = 8192; sp->opt.maxXmitDataSegmentLength = 8192; - sp->opt.maxBurstLength = 65536; // 64k + sp->opt.maxluns = ISCSI_MAX_LUNS; - sdebug(2, "sessionID=%d sp=%p", n, sp); error = ism_start(sp); return error; @@ -663,7 +676,7 @@ static void iscsi_shutdown(void *v) { - struct isc_softc *sc = (struct isc_softc *)v; + struct isc_softc *sc = v; isc_session_t *sp; int n; @@ -672,12 +685,14 @@ xdebug("sc is NULL!"); return; } +#ifdef DO_EVENTHANDLER if(sc->eh == NULL) debug(2, "sc->eh is NULL"); else { EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->eh); debug(2, "done n=%d", sc->nsess); } +#endif n = 0; TAILQ_FOREACH(sp, &sc->isc_sess, sp_link) { debug(2, "%2d] sp->flags=0x%08x", n, sp->flags); @@ -686,24 +701,6 @@ debug(2, "done"); } -static int -init_pdus(struct isc_softc *sc) -{ - debug_called(8); - - sc->pdu_zone = uma_zcreate("pdu", sizeof(pduq_t), - NULL, NULL, NULL, NULL, - 0, 0); - if(sc->pdu_zone == NULL) { - printf("iscsi_initiator: uma_zcreate failed"); - return -1; - } - uma_zone_set_max(sc->pdu_zone, MAX_PDUS); - TAILQ_INIT(&sc->freepdu); - - return 0; -} - static void free_pdus(struct isc_softc *sc) { @@ -724,50 +721,52 @@ static void iscsi_start(void) { - struct isc_softc *sc = &isc; - debug_called(8); - memset(sc, 0, sizeof(struct isc_softc)); + TUNABLE_INT_FETCH("net.iscsi_initiator.max_sessions", &max_sessions); + TUNABLE_INT_FETCH("net.iscsi_initiator.max_pdus", &max_pdus); - sc->dev = make_dev(&iscsi_cdevsw, MAX_SESSIONS, UID_ROOT, GID_WHEEL, 0600, "iscsi"); - sc->dev->si_drv1 = sc; + isc = malloc(sizeof(struct isc_softc), M_ISCSI, M_ZERO|M_WAITOK); + isc->dev = make_dev(&iscsi_cdevsw, max_sessions, UID_ROOT, GID_WHEEL, 0600, "iscsi"); + isc->dev->si_drv1 = isc; + mtx_init(&isc->isc_mtx, "iscsi", NULL, MTX_DEF); + mtx_init(&isc->pdu_mtx, "iscsi pdu pool", NULL, MTX_DEF); - TAILQ_INIT(&sc->isc_sess); - if(init_pdus(sc) != 0) - xdebug("pdu zone init failed!"); // XXX: should cause terminal failure ... - - mtx_init(&sc->mtx, "iscsi", NULL, MTX_DEF); - mtx_init(&sc->pdu_mtx, "iscsi pdu pool", NULL, MTX_DEF); + TAILQ_INIT(&isc->isc_sess); + /* + | now init the free pdu list + */ + isc->pdu_zone = uma_zcreate("pdu", sizeof(pduq_t), + NULL, NULL, NULL, NULL, + 0, 0); + if(isc->pdu_zone == NULL) { + xdebug("iscsi_initiator: uma_zcreate failed"); + // XXX: should fail... + } + uma_zone_set_max(isc->pdu_zone, max_pdus); + TAILQ_INIT(&isc->freepdu); + isc->unit = new_unrhdr(0, max_sessions-1, NULL); + sx_init(&isc->unit_sx, "iscsi sx"); -#if 0 - // XXX: this will cause a panic if the - // module is loaded too early - if(ic_init(sc) != 0) - return; -#else - sc->cam_sim = NULL; -#endif - #ifdef DO_EVENTHANDLER - if((sc->eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, iscsi_shutdown, + if((isc->eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, iscsi_shutdown, sc, SHUTDOWN_PRI_DEFAULT-1)) == NULL) xdebug("shutdown event registration failed\n"); #endif /* | sysctl stuff */ - sysctl_ctx_init(&sc->clist); - sc->oid = SYSCTL_ADD_NODE(&sc->clist, + sysctl_ctx_init(&isc->clist); + isc->oid = SYSCTL_ADD_NODE(&isc->clist, SYSCTL_STATIC_CHILDREN(_net), OID_AUTO, - "iscsi", + "iscsi_initiator", CTLFLAG_RD, 0, "iSCSI Subsystem"); - SYSCTL_ADD_STRING(&sc->clist, - SYSCTL_CHILDREN(sc->oid), + SYSCTL_ADD_STRING(&isc->clist, + SYSCTL_CHILDREN(isc->oid), OID_AUTO, "driver_version", CTLFLAG_RD, @@ -775,8 +774,8 @@ 0, "iscsi driver version"); - SYSCTL_ADD_STRING(&sc->clist, - SYSCTL_CHILDREN(sc->oid), + SYSCTL_ADD_STRING(&isc->clist, + SYSCTL_CHILDREN(isc->oid), OID_AUTO, "isid", CTLFLAG_RW, @@ -784,13 +783,13 @@ 6+1, "initiator part of the Session Identifier"); - SYSCTL_ADD_INT(&sc->clist, - SYSCTL_CHILDREN(sc->oid), + SYSCTL_ADD_INT(&isc->clist, + SYSCTL_CHILDREN(isc->oid), OID_AUTO, "sessions", CTLFLAG_RD, - &sc->nsess, - sizeof(sc->nsess), + &isc->nsess, + sizeof(isc->nsess), "number of active session"); printf("iscsi: version %s\n", iscsi_driver_version); @@ -804,7 +803,6 @@ static void iscsi_stop(void) { - struct isc_softc *sc = &isc; isc_session_t *sp, *sp_tmp; debug_called(8); @@ -813,24 +811,26 @@ | go through all the sessions | Note: close should have done this ... */ - TAILQ_FOREACH_SAFE(sp, &sc->isc_sess, sp_link, sp_tmp) { + TAILQ_FOREACH_SAFE(sp, &isc->isc_sess, sp_link, sp_tmp) { //XXX: check for activity ... ism_stop(sp); + if(sp->cam_sim != NULL) + ic_destroy(sp); } - if(sc->cam_sim != NULL) - ic_destroy(sc); + mtx_destroy(&isc->isc_mtx); + mtx_destroy(&isc->pdu_mtx); + sx_destroy(&isc->unit_sx); - mtx_destroy(&sc->mtx); - mtx_destroy(&sc->pdu_mtx); - free_pdus(sc); + free_pdus(isc); - if(sc->dev) - destroy_dev(sc->dev); + if(isc->dev) + destroy_dev(isc->dev); - if(sysctl_ctx_free(&sc->clist)) + if(sysctl_ctx_free(&isc->clist)) xdebug("sysctl_ctx_free failed"); - iscsi_shutdown(sc); // XXX: check EVENTHANDLER_ ... + iscsi_shutdown(isc); // XXX: check EVENTHANDLER_ ... + free(isc, M_ISCSI); } static int @@ -844,13 +844,12 @@ break; case MOD_QUIESCE: -#if 1 - if(isc.nsess) { - xdebug("iscsi module busy(nsess=%d), cannot unload", isc.nsess); + if(isc->nsess) { + xdebug("iscsi module busy(nsess=%d), cannot unload", isc->nsess); log(LOG_ERR, "iscsi module busy, cannot unload"); } - return isc.nsess; -#endif + return isc->nsess; + case MOD_SHUTDOWN: break; Index: sys/dev/iscsi/initiator/isc_sm.c =================================================================== --- sys/dev/iscsi/initiator/isc_sm.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_sm.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ */ /* | iSCSI - Session Manager - | $Id: isc_sm.c,v 1.30 2007/04/22 09:53:09 danny Exp danny $ + | $Id: isc_sm.c 743 2009-08-08 10:54:53Z danny $ */ #include @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -131,8 +132,10 @@ debug_called(8); opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 0); debug(5, "itt=%x pq=%p opq=%p", ntohl(pq->pdu.ipdu.bhs.itt), pq, opq); - if(opq != NULL) + if(opq != NULL) { iscsi_done(sp, opq, pq); + i_acked_hld(sp, &pq->pdu); + } else xdebug("%d] we lost something itt=%x", sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); @@ -267,7 +270,7 @@ len += pp->ahs_len; bhp->AHSLength = pp->ahs_len / 4; } - if(sp->hdrDigest) + if(ISOK2DIG(sp->hdrDigest, pp)) len += 4; if(pp->ds_len) { n = pp->ds_len; @@ -283,7 +286,7 @@ n = 4 - (len & 03); len += n; } - if(sp->dataDigest) + if(ISOK2DIG(sp->dataDigest, pp)) len += 4; } @@ -321,7 +324,7 @@ mtx_lock(&sp->io_mtx); sp->flags |= ISC_OQNOTEMPTY; if(sp->flags & ISC_OWAITING) - wakeup(&sp->flags); + wakeup(&sp->flags); mtx_unlock(&sp->io_mtx); return error; @@ -329,7 +332,7 @@ /* | called when a fullPhase is restarted */ -static void +void ism_restart(isc_session_t *sp) { int lastcmd; @@ -348,32 +351,9 @@ } mtx_unlock(&sp->io_mtx); - sdebug(2, "restarted lastcmd=0x%x", lastcmd); + sdebug(2, "restarted sn.cmd=0x%x lastcmd=0x%x", sp->sn.cmd, lastcmd); } -int -ism_fullfeature(struct cdev *dev, int flag) -{ - isc_session_t *sp = (isc_session_t *)dev->si_drv2; - int error; - - sdebug(2, "flag=%d", flag); - - error = 0; - switch(flag) { - case 0: // stop - sp->flags &= ~ISC_FFPHASE; - break; - case 1: // start - error = ic_fullfeature(dev); - break; - case 2: // restart - ism_restart(sp); - break; - } - return error; -} - void ism_recv(isc_session_t *sp, pduq_t *pq) { @@ -384,26 +364,6 @@ bhs = &pq->pdu.ipdu.bhs; statSN = ntohl(bhs->OpcodeSpecificFields[1]); -#if 0 - { - /* - | this code is only for debugging. - */ - sn_t *sn = &sp->sn; - if(sp->cws == 0) { - if((sp->flags & ISC_STALLED) == 0) { - sdebug(4, "window closed: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", - sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); - sp->flags |= ISC_STALLED; - } else - if(sp->flags & ISC_STALLED) { - sdebug(4, "window opened: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", - sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); - sp->flags &= ~ISC_STALLED; - } - } - } -#endif #ifdef notyet if(sp->sn.expCmd != sn->cmd) { @@ -454,7 +414,7 @@ break; } } - + /* | go through the out queues looking for work | if either nothing to do, or window is closed @@ -465,11 +425,10 @@ { sn_t *sn = &sp->sn; pduq_t *pq; - int error, ndone; - int which; + int error, which; debug_called(8); - error = ndone = 0; + error = 0; while(sp->flags & ISC_LINK_UP) { pdu_t *pp; @@ -508,7 +467,7 @@ sn->cmd++; case ISCSI_WRITE_DATA: - bhs->ExpStSN = htonl(sn->stat); + bhs->ExpStSN = htonl(sn->stat + 1); break; default: @@ -523,19 +482,21 @@ bhs->opcode, sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt); - if(pq->ccb) + if(bhs->opcode != ISCSI_NOP_OUT) + /* + | enqued till ack is received + | note: sosend(...) does not mean the packet left + | the host so that freeing resources has to wait + */ i_nqueue_hld(sp, pq); - if((error = isc_sendPDU(sp, pq)) == 0) { - ndone++; - if(pq->ccb == NULL) - pdu_free(sp->isc, pq); - } - else { - xdebug("error=%d ndone=%d opcode=0x%x ccb=%p itt=%x", - error, ndone, bhs->opcode, pq->ccb, ntohl(bhs->itt)); - if(pq->ccb) - i_remove_hld(sp, pq); + error = isc_sendPDU(sp, pq); + if(bhs->opcode == ISCSI_NOP_OUT) + pdu_free(sp->isc, pq); + if(error) { + xdebug("error=%d opcode=0x%x ccb=%p itt=%x", + error, bhs->opcode, pq->ccb, ntohl(bhs->itt)); + i_remove_hld(sp, pq); switch(error) { case EPIPE: sp->flags &= ~ISC_LINK_UP; @@ -546,12 +507,12 @@ break; default: - if(pq->ccb) { + if(pq->ccb) { xdebug("back to cam"); pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error? - XPT_DONE(sp->isc, pq->ccb); + XPT_DONE(sp, pq->ccb); pdu_free(sp->isc, pq); - } + } else xdebug("we lost it!"); } @@ -559,12 +520,12 @@ } return error; } - + /* | survives link breakdowns. */ static void -ism_proc(void *vp) +ism_out(void *vp) { isc_session_t *sp = (isc_session_t *)vp; int error; @@ -580,8 +541,11 @@ sdebug(3, "error=%d", error); } } - mtx_lock(&sp->io_mtx); + mtx_lock(&sp->io_mtx); if((sp->flags & ISC_LINK_UP) == 0) { + sdebug(3, "ISC_LINK_UP==0, sp->flags=%x ", sp->flags); + if(sp->soc != NULL) + sdebug(3, "so_state=%x", sp->soc->so_state); wakeup(&sp->soc); } @@ -589,7 +553,7 @@ sp->flags |= ISC_OWAITING; if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) { if(sp->flags & ISC_CON_RUNNING) - _nop_out(sp); + _nop_out(sp); } sp->flags &= ~ISC_OWAITING; } @@ -600,14 +564,20 @@ sp->flags &= ~ISC_SM_RUNNING; sdebug(3, "dropped ISC_SM_RUNNING"); + wakeup(&sp->soc); + wakeup(sp); // XXX: do we need this one? + #if __FreeBSD_version >= 700000 destroy_dev(sp->dev); #endif - wakeup(sp); debug(3, "terminated sp=%p sp->sid=%d", sp, sp->sid); +#if __FreeBSD_version >= 800000 kproc_exit(0); +#else + kthread_exit(0); +#endif } #if 0 @@ -753,12 +723,16 @@ (void)i_pdu_flush(sp); - ic_lost_target(sp, sp->sid); + ic_destroy(sp); - mtx_lock(&sc->mtx); + sx_xlock(&sc->unit_sx); + free_unr(sc->unit, sp->sid); + sx_xunlock(&sc->unit_sx); + + mtx_lock(&sc->isc_mtx); TAILQ_REMOVE(&sc->isc_sess, sp, sp_link); sc->nsess--; - mtx_unlock(&sc->mtx); + mtx_unlock(&sc->isc_mtx); #if __FreeBSD_version < 700000 destroy_dev(sp->dev); @@ -771,7 +745,6 @@ mtx_destroy(&sp->io_mtx); i_freeopt(&sp->opt); - sc->sessions[sp->sid] = NULL; if(sysctl_ctx_free(&sp->clist)) xdebug("sysctl_ctx_free failed"); @@ -792,17 +765,11 @@ TAILQ_INIT(&sp->isnd); TAILQ_INIT(&sp->wsnd); TAILQ_INIT(&sp->hld); -#if 1 + mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_DEF); mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_DEF); mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_DEF); mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_DEF); -#else - mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_SPIN); - mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_SPIN); - mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_SPIN); - mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_SPIN); -#endif mtx_init(&sp->io_mtx, "iscsi-io", NULL, MTX_DEF); isc_add_sysctls(sp); @@ -810,5 +777,10 @@ sp->flags |= ISC_SM_RUN; debug(4, "starting ism_proc: sp->sid=%d", sp->sid); - return kproc_create(ism_proc, sp, &sp->stp, 0, 0, "ism_%d", sp->sid); + +#if __FreeBSD_version >= 800000 + return kproc_create(ism_out, sp, &sp->stp, 0, 0, "isc_out %d", sp->sid); +#else + return kthread_create(ism_out, sp, &sp->stp, 0, 0, "isc_out %d", sp->sid); +#endif } --=-=-=-- From owner-freebsd-scsi@FreeBSD.ORG Wed Jul 28 08:41:14 2010 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 95ED31065674 for ; Wed, 28 Jul 2010 08:41:14 +0000 (UTC) (envelope-from des@des.no) Received: from smtp.des.no (smtp.des.no [194.63.250.102]) by mx1.freebsd.org (Postfix) with ESMTP id E095E8FC08 for ; Wed, 28 Jul 2010 08:41:13 +0000 (UTC) Received: from ds4.des.no (des.no [84.49.246.2]) by smtp.des.no (Postfix) with ESMTP id B40821FFC33; Wed, 28 Jul 2010 08:41:11 +0000 (UTC) Received: by ds4.des.no (Postfix, from userid 1001) id 8445A84525; Wed, 28 Jul 2010 10:41:11 +0200 (CEST) From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= To: Daniel Braniss References: <86k4ogoyy7.fsf@ds4.des.no> <86fwz4oxqw.fsf@ds4.des.no> <86bp9soxlj.fsf@ds4.des.no> Date: Wed, 28 Jul 2010 10:41:11 +0200 In-Reply-To: <86bp9soxlj.fsf@ds4.des.no> ("Dag-Erling =?utf-8?Q?Sm=C3=B8rg?= =?utf-8?Q?rav=22's?= message of "Wed, 28 Jul 2010 09:48:56 +0200") Message-ID: <86y6cwngm0.fsf@ds4.des.no> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Cc: freebsd-scsi@freebsd.org Subject: Re: iscsi_initiator patches X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2010 08:41:14 -0000 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable New new patch with WARNS=3D3 fixes. DES --=20 Dag-Erling Sm=C3=B8rgrav - des@des.no --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=iscsi-des.diff Index: sbin/iscontrol/iscsi.conf.5 =================================================================== --- sbin/iscontrol/iscsi.conf.5 (revision 210555) +++ sbin/iscontrol/iscsi.conf.5 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007-2008 Daniel Braniss +.\" Copyright (c) 2007-2010 Daniel Braniss .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -68,6 +68,7 @@ Default is none. .It Cm DataDigest same as for HeaderDigest, but on the data part of the iSCSI PDU. +(not yet tested) .It Cm MaxConnections is the number of simultaneous connections per session, currently only 1. Index: sbin/iscontrol/iscontrol.8 =================================================================== --- sbin/iscontrol/iscontrol.8 (revision 210555) +++ sbin/iscontrol/iscontrol.8 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007-2008 Daniel Braniss +.\" Copyright (c) 2007-2010 Daniel Braniss .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -32,11 +32,12 @@ .Nd login/negotiator/control for an iSCSI initiator session .Sh SYNOPSIS .Nm -.Op Fl vd +.Op Fl dv .Oo -.Op Fl c Ar file +.Fl c Ar file .Op Fl n Ar nickname .Oc +.Op Fl p Ar pidfile .Op Fl t Ar target .Op Ar variable Ns = Ns Ar value .Sh DESCRIPTION @@ -57,26 +58,29 @@ when a SIGHUP signal is received. The flags are as follows: .Bl -tag -width variable=value -.It Fl v -verbose mode. -.It Fl d -do a -.Em discovery session -and exit. .It Fl c Ar file a file containing configuration .Em key-options , see -.Xr iscsi.conf 5 +.Xr iscsi.conf 5 . +.It Fl d +do a +.Em discovery session +and exit. .It Fl n Ar nickname if .Sy -c file is specified, then search for the block named .Em nickname in that file, see -.Xr iscsi.conf 5 +.Xr iscsi.conf 5 . +.It Fl p Ar pidfile +will write the process ID of the session to the specified +.Em pidfile .It Fl t Ar target -is the target's IP address or name +the target's IP address or name. +.It Fl v +verbose mode. .It Ar variable Ns = Ns Ar value see .Xr iscsi.conf 5 @@ -86,13 +90,13 @@ .Sh EXAMPLES .Dl iscontrol -dt myiscsitarget .Pp -will start a +will start a .Em discovery session with the target and print to stdout the list of available targetnames/targetadresses. Note: this listing does not necessarily mean availability, since depending on the target configuration, a discovery session might -not need login/access permission, but a +not need login/access permission, but a .Em full session certainly does. .sp Index: sbin/iscontrol/iscontrol.h =================================================================== --- sbin/iscontrol/iscontrol.h (revision 210555) +++ sbin/iscontrol/iscontrol.h (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -154,7 +154,7 @@ void parseConfig(FILE *fd, char *key, isc_opt_t *op); char *chapDigest(char *ap, char id, char *cp, char *chapSecret); -char *genChapChallenge(char *encoding, int len); +char *genChapChallenge(char *encoding, uint len); int str2bin(char *str, char **rsp); char *bin2str(char *fmt, unsigned char *md, int blen); Index: sbin/iscontrol/config.c =================================================================== --- sbin/iscontrol/config.c (revision 210555) +++ sbin/iscontrol/config.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2009 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" /* @@ -94,6 +94,11 @@ #define OPT_iqn 34 #define OPT_sockbufsize 35 +/* + | sentinel + */ +#define OPT_end 0 + #define _OFF(v) ((int)&((isc_opt_t *)NULL)->v) #define _E(u, s, v) {.usage=u, .scope=s, .name=#v, .tokenID=OPT_##v} @@ -145,7 +150,7 @@ _E(U_LO, S_SW, sessionType), - {0} + _E(0, 0, end) }; #define _OPT_INT(w) strtol((char *)w, NULL, 0) @@ -154,7 +159,7 @@ static __inline int _OPT_BOOL(char *w) { - if(isalpha(*w)) + if(isalpha((unsigned char)*w)) return strcasecmp(w, "TRUE") == 0; else return _OPT_INT(w); @@ -244,12 +249,12 @@ len = 0; state = 0; while((lp = getline(fd)) != NULL) { - for(; isspace(*lp); lp++) + for(; isspace((unsigned char)*lp); lp++) ; switch(state) { case 0: if((p = strchr(lp, '{')) != NULL) { - while((--p > lp) && *p && isspace(*p)); + while((--p > lp) && *p && isspace((unsigned char)*p)); n = p - lp; if(len && strncmp(lp, key, MAX(n, len)) == 0) state = 2; @@ -272,7 +277,7 @@ } - for(p = &lp[strlen(lp)-1]; isspace(*p); p--) + for(p = &lp[strlen(lp)-1]; isspace((unsigned char)*p); p--) *p = 0; if((*nargs)-- > 0) *ar++ = strdup(lp); @@ -351,9 +356,9 @@ continue; *p = 0; v = p + 1; - while(isspace(*--p)) + while(isspace((unsigned char)*--p)) *p = 0; - while(isspace(*v)) + while(isspace((unsigned char)*v)) v++; if((tk = keyLookup(*ar)) == NULL) continue; Index: sbin/iscontrol/fsm.c =================================================================== --- sbin/iscontrol/fsm.c (revision 210555) +++ sbin/iscontrol/fsm.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" typedef enum { @@ -99,26 +99,26 @@ #ifdef notyet { time_t sec; - // make sure we are not in a loop - // XXX: this code has to be tested - sec = time(0) - sess->reconnect_time; - if(sec > (5*60)) { - // if we've been connected for more that 5 minutes - // then just reconnect - sess->reconnect_time = sec; - sess->reconnect_cnt1 = 0; - } - else { - // - sess->reconnect_cnt1++; - if((sec / sess->reconnect_cnt1) < 2) { - // if less that 2 seconds from the last reconnect - // we are most probably looping - syslog(LOG_CRIT, "too many reconnects %d", sess->reconnect_cnt1); - return 0; + // make sure we are not in a loop + // XXX: this code has to be tested + sec = time(0) - sess->reconnect_time; + if(sec > (5*60)) { + // if we've been connected for more that 5 minutes + // then just reconnect + sess->reconnect_time = sec; + sess->reconnect_cnt1 = 0; } + else { + // + sess->reconnect_cnt1++; + if((sec / sess->reconnect_cnt1) < 2) { + // if less that 2 seconds from the last reconnect + // we are most probably looping + syslog(LOG_CRIT, "too many reconnects %d", sess->reconnect_cnt1); + return 0; + } + } } - } #endif sess->reconnect_cnt++; } @@ -140,13 +140,13 @@ if (soc == -1) continue; - // from Patrick.Guelat@imp.ch: - // iscontrol can be called without waiting for the socket entry to time out - val = 1; + // from Patrick.Guelat@imp.ch: + // iscontrol can be called without waiting for the socket entry to time out + val = 1; if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &val, (socklen_t)sizeof(val)) < 0) { - fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n", - errno, strerror(errno)); - } + fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n", + errno, strerror(errno)); + } if(connect(soc, res->ai_addr, res->ai_addrlen) == 0) break; @@ -196,7 +196,7 @@ } sess->flags |= SESS_CONNECTED; return T1; - } + } fprintf(stderr, "errno=%d\n", sv_errno); perror("connect"); @@ -289,7 +289,7 @@ // XXX: this has to go size_t n; n = sizeof(sess->isid); - if(sysctlbyname("net.iscsi.isid", (void *)sess->isid, (size_t *)&n, 0, 0) != 0) + if(sysctlbyname("net.iscsi_initiator.isid", (void *)sess->isid, (size_t *)&n, 0, 0) != 0) perror("sysctlbyname"); } if(ioctl(fd, ISCSISETSES, &n)) { @@ -343,29 +343,29 @@ } } -static void +static int doCAM(isess_t *sess) { char pathstr[1024]; union ccb *ccb; - int i; + int i, n; if(ioctl(sess->fd, ISCSIGETCAM, &sess->cam) != 0) { syslog(LOG_WARNING, "ISCSIGETCAM failed: %d", errno); - return; + return 0; } - debug(2, "nluns=%d", sess->cam.target_nluns); + debug(1, "nluns=%d", sess->cam.target_nluns); /* | for now will do this for each lun ... */ - for(i = 0; i < sess->cam.target_nluns; i++) { + for(n = i = 0; i < sess->cam.target_nluns; i++) { debug(2, "CAM path_id=%d target_id=%d target_lun=%d", sess->cam.path_id, sess->cam.target_id, sess->cam.target_lun[i]); sess->camdev = cam_open_btl(sess->cam.path_id, sess->cam.target_id, - sess->cam.target_lun[i], O_RDWR, NULL); + i, O_RDWR, NULL); if(sess->camdev == NULL) { - syslog(LOG_WARNING, "%s", cam_errbuf); + //syslog(LOG_WARNING, "%s", cam_errbuf); debug(3, "%s", cam_errbuf); continue; } @@ -378,20 +378,21 @@ ccb->ccb_h.func_code = XPT_REL_SIMQ; ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; ccb->crs.openings = sess->op->tags; - if(cam_send_ccb(sess->camdev, ccb) < 0) - syslog(LOG_WARNING, "%s", cam_errbuf); + debug(2, "%s", cam_errbuf); else if((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { syslog(LOG_WARNING, "XPT_REL_SIMQ CCB failed"); // cam_error_print(sess->camdev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } - else + else { + n++; syslog(LOG_INFO, "%s tagged openings now %d\n", pathstr, ccb->crs.openings); - + } cam_freeccb(ccb); cam_close_device(sess->camdev); } + return n; } static trans_t @@ -417,7 +418,15 @@ perror("daemon"); exit(1); } + if(sess->op->pidfile != NULL) { + FILE *pidf; + pidf = fopen(sess->op->pidfile, "w"); + if(pidf != NULL) { + fprintf(pidf, "%d\n", getpid()); + fclose(pidf); + } + } openlog("iscontrol", LOG_CONS|LOG_PERROR|LOG_PID|LOG_NDELAY, LOG_KERN); syslog(LOG_INFO, "running"); @@ -426,7 +435,11 @@ perror("ISCSISTART"); return -1; } - doCAM(sess); + if(doCAM(sess) == 0) { + syslog(LOG_WARNING, "no device found"); + ioctl(sess->fd, ISCSISTOP); + return T15; + } } else { @@ -449,7 +462,8 @@ sess->flags |= SESS_FULLFEATURE; sess->flags &= ~(SESS_REDIRECT | SESS_RECONNECT); - printf("iscontrol: supervise starting main loop\n"); + if(vflag) + printf("iscontrol: supervise starting main loop\n"); /* | the main loop - actually do nothing | all the work is done inside the kernel @@ -468,14 +482,14 @@ } if(sess->flags & SESS_DISCONNECT) { + sess->flags &= ~SESS_FULLFEATURE; + return T9; + } + else { val = 0; if(ioctl(sess->fd, ISCSISTOP, &val)) { perror("ISCSISTOP"); } - sess->flags &= ~SESS_FULLFEATURE; - return T9; - } - else { sess->flags |= SESS_INITIALLOGIN1; } return T8; @@ -490,7 +504,7 @@ debug_called(3); len = pp->ds_len; - ptr = pp->ds; + ptr = pp->ds_addr; while(len > 0) { if(*ptr != 0) printf("%s\n", ptr); @@ -579,8 +593,13 @@ static int handleLogoutResp(isess_t *sess, pdu_t *pp) { - if(sess->flags & SESS_DISCONNECT) + if(sess->flags & SESS_DISCONNECT) { + int val = 0; + if(ioctl(sess->fd, ISCSISTOP, &val)) { + perror("ISCSISTOP"); + } return 0; + } return T13; } Index: sbin/iscontrol/login.c =================================================================== --- sbin/iscontrol/login.c (revision 210555) +++ sbin/iscontrol/login.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" static char *status_class1[] = { @@ -107,7 +107,7 @@ debug_called(3); len = pp->ds_len; - ptr = (char *)pp->ds; + ptr = (char *)pp->ds_addr; klen = strlen(key); while(len > klen) { if(strncmp(key, ptr, klen) == 0) @@ -163,7 +163,7 @@ debug_called(3); len = pp->ds_len; - ptr = (char *)pp->ds; + ptr = (char *)pp->ds_addr; while(len > 0) { if(vflag > 1) printf("got: len=%d %s\n", len, ptr); @@ -233,7 +233,7 @@ st_class = status >> 8; if(status) { - int st_detail = status & 0xff; + uint st_detail = status & 0xff; switch(st_class) { case 1: // Redirect Index: sbin/iscontrol/pdu.c =================================================================== --- sbin/iscontrol/pdu.c (revision 210555) +++ sbin/iscontrol/pdu.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,10 +43,10 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" -static void pukeText(char *it, pdu_t *pp); +static void pukeText(char *it, pdu_t *pp); int xmitpdu(isess_t *sess, pdu_t *pp) @@ -85,7 +85,7 @@ int res; pp->ahs_size = 8 * 1024; - if((pp->ahs = malloc(pp->ahs_size)) == NULL) { + if((pp->ahs_addr = malloc(pp->ahs_size)) == NULL) { fprintf(stderr, "out of mem!"); return -1; } @@ -126,16 +126,16 @@ if((pp->ds_len + len) > pp->ds_size) { u_char *np; - np = realloc(pp->ds, pp->ds_size + len + FUDGE); + np = realloc(pp->ds_addr, pp->ds_size + len + FUDGE); if(np == NULL) { free(str); //XXX: out of memory! return -1; } - pp->ds = np; + pp->ds_addr = np; pp->ds_size += len + FUDGE; } - memcpy(pp->ds + pp->ds_len, str, len); + memcpy(pp->ds_addr + pp->ds_len, str, len); pp->ds_len += len; free(str); return len; @@ -145,12 +145,12 @@ freePDU(pdu_t *pp) { if(pp->ahs_size) - free(pp->ahs); + free(pp->ahs_addr); if(pp->ds_size) - free(pp->ds); + free(pp->ds_addr); bzero(&pp->ipdu, sizeof(union ipdu_u)); - pp->ahs = NULL; - pp->ds = NULL; + pp->ahs_addr = NULL; + pp->ds_addr = NULL; pp->ahs_size = 0; pp->ds_size = pp->ds_len = 0; } @@ -163,7 +163,7 @@ size_t len, n; len = pp->ds_len; - ptr = (char *)pp->ds; + ptr = (char *)pp->ds_addr; cmd = pp->ipdu.bhs.opcode; printf("%s: cmd=0x%x len=%d\n", it, cmd, (int)len); Index: sbin/iscontrol/misc.c =================================================================== --- sbin/iscontrol/misc.c (revision 210555) +++ sbin/iscontrol/misc.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,9 @@ #include #include +#include +#include "iscontrol.h" + static inline char c2b(unsigned char c) { Index: sbin/iscontrol/Makefile =================================================================== --- sbin/iscontrol/Makefile (revision 210555) +++ sbin/iscontrol/Makefile (working copy) @@ -4,9 +4,10 @@ PROG= iscontrol DPADD= ${LIBCAM} ${LIBMD} LDADD= -lcam -lmd +S= ${.CURDIR}/../../sys -WARNS?= 2 -CFLAGS += -I${.CURDIR}/../../sys/dev/iscsi/initiator +WARNS?= 3 +CFLAGS += -I$S #CFLAGS += -g -DDEBUG MAN= iscsi.conf.5 iscontrol.8 Index: sbin/iscontrol/auth_subr.c =================================================================== --- sbin/iscontrol/auth_subr.c (revision 210555) +++ sbin/iscontrol/auth_subr.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" static int @@ -152,7 +152,7 @@ } char * -genChapChallenge(char *encoding, int len) +genChapChallenge(char *encoding, uint len) { int fd; unsigned char tmp[1024]; Index: sbin/iscontrol/iscontrol.c =================================================================== --- sbin/iscontrol/iscontrol.c (revision 210555) +++ sbin/iscontrol/iscontrol.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,16 +53,12 @@ #include #include -#include "iscsi.h" +#include #include "iscontrol.h" -#define USAGE "[-v] [-d] [-c config] [-n name] [-t target] " -#define OPTIONS "vdc:t:n:" +#define USAGE "[-v] [-d] [-c config] [-n name] [-t target] [-p pidfile]" +#define OPTIONS "vdc:t:n:p:" -#ifndef DEBUG -//int vflag; -#endif - token_t AuthMethods[] = { {"None", NONE}, {"KRB5", KRB5}, @@ -70,14 +66,14 @@ {"SPKM2", SPKM2}, {"SRP", SRP}, {"CHAP", CHAP}, - {0} + {0, 0} }; token_t DigestMethods[] = { {"None", 0}, {"CRC32", 1}, {"CRC32C", 1}, - {0} + {0, 0} }; u_char isid[6 + 6]; @@ -128,7 +124,7 @@ main(int cc, char **vv) { int ch, disco; - char *pname, *p, *q, *ta, *kw; + char *pname, *pidfile, *p, *q, *ta, *kw; isc_opt_t *op; FILE *fd; @@ -141,6 +137,7 @@ kw = ta = 0; disco = 0; + pidfile = NULL; while((ch = getopt(cc, vv, OPTIONS)) != -1) { switch(ch) { @@ -163,6 +160,9 @@ case 'n': kw = optarg; break; + case 'p': + pidfile = optarg; + break; default: badu: fprintf(stderr, "Usage: %s %s\n", pname, USAGE); @@ -225,7 +225,7 @@ op->sessionType = "Discovery"; op->targetName = 0; } - + op->pidfile = pidfile; fsm(op); exit(0); Index: sbin/iscontrol/pdu.h =================================================================== --- sbin/iscontrol/pdu.h (revision 210555) +++ sbin/iscontrol/pdu.h (working copy) @@ -1,134 +0,0 @@ -/*- - * Copyright (c) 2005 Daniel Braniss - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - | $Id: pdu.h,v 2.1 2006/11/12 08:06:51 danny Exp $ - */ - -/* - | keep in BIG endian order (network byte order). - */ - -typedef struct login_req { - char cmd; // 0x03 - - u_char NSG:2; - u_char CSG:2; - u_char _:2; - u_char C:1; - u_char T:1; - - char v_max; - char v_min; - - int len; // remapped via standard bhs - char isid[6]; - short tsih; - int itt; // Initiator Task Tag; - - int CID:16; - int rsv:16; - - int cmdSN; - int expStatSN; - int unused[4]; -} login_req_t; - -typedef struct login_rsp { - char cmd; // 0x23 - u_char NSG:2; - u_char CSG:2; - u_char _1:2; - u_char C:1; - u_char T:1; - - char v_max; - char v_act; - - int len; // remapped via standard bhs - char isid[6]; - short tsih; - int itt; // Initiator Task Tag; - int _2; - rsp_sn_t sn; - int status:16; - int _3:16; - int _4[2]; -} login_rsp_t; - -typedef struct text_req { - char cmd; // 0x04 - - u_char _1:6; - u_char C:1; // Continuation - u_char F:1; // Final - char _2[2]; - - int len; - int itt; // Initiator Task Tag - int LUN[2]; - int ttt; // Target Transfer Tag - int cmdSN; - int expStatSN; - int unused[4]; -} text_req_t; - -/* - | Responses - */ -typedef struct logout_req { - char cmd; // 0x06 - char reason; // 0 - close session - // 1 - close connection - // 2 - remove the connection for recovery - char _2[2]; - - int len; - int _r[2]; - int itt; // Initiator Task Tag; - - u_int CID:16; - u_int rsv:16; - - int cmdSN; - int expStatSN; - int unused[4]; -} logout_req_t; - -typedef struct logout_rsp { - char cmd; // 0x26 - char cbits; - char _1[2]; - int len; - int _2[2]; - int itt; - int _3; - rsp_sn_t sn; - short time2wait; - short time2retain; - int _4; -} logout_rsp_t; Index: sys/dev/iscsi/initiator/isc_cam.c =================================================================== --- sys/dev/iscsi/initiator/isc_cam.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_cam.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,9 @@ * SUCH DAMAGE. * */ - +/* + | $Id: isc_cam.c 998 2009-12-20 10:32:45Z danny $ + */ #include __FBSDID("$FreeBSD$"); @@ -43,6 +45,7 @@ #include #include #include +#include #include #include @@ -53,52 +56,72 @@ #include #include -// XXX: untested/incomplete -void -ic_freeze(isc_session_t *sp) +static void +_inq(struct cam_sim *sim, union ccb *ccb) { + struct ccb_pathinq *cpi = &ccb->cpi; + isc_session_t *sp = cam_sim_softc(sim); + debug_called(8); -#if 0 - sdebug(2, "freezing path=%p", sp->cam_path == NULL? 0: sp->cam_path); - if((sp->cam_path != NULL) && !(sp->flags & ISC_FROZEN)) { - xpt_freeze_devq(sp->cam_path, 1); - } + debug(3, "sid=%d target=%d lun=%d", sp->sid, ccb->ccb_h.target_id, ccb->ccb_h.target_lun); + + cpi->version_num = 1; /* XXX??? */ + cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_32; + cpi->target_sprt = 0; + cpi->hba_misc = 0; + cpi->hba_eng_cnt = 0; + cpi->max_target = 0; //ISCSI_MAX_TARGETS - 1; + cpi->initiator_id = ISCSI_MAX_TARGETS; + cpi->max_lun = sp->opt.maxluns - 1; + cpi->bus_id = cam_sim_bus(sim); + cpi->base_transfer_speed = 3300; // 40000; // XXX: + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + cpi->transport = XPORT_ISCSI; + cpi->transport_version = 0; + cpi->ccb_h.status = CAM_REQ_CMP; +#if defined(KNOB_VALID_ADDRESS) + cpi->transport = XPORT_ISCSI; + cpi->transport_version = 0; #endif - sp->flags |= ISC_FROZEN; } -// XXX: untested/incomplete -void -ic_release(isc_session_t *sp) +static __inline int +_scsi_encap(struct cam_sim *sim, union ccb *ccb) { - debug_called(8); -#if 0 - sdebug(2, "release path=%p", sp->cam_path == NULL? 0: sp->cam_path); - if((sp->cam_path != NULL) && (sp->flags & ISC_FROZEN)) { - xpt_release_devq(sp->cam_path, 1, TRUE); - } + int ret; + +#if __FreeBSD_version < 700000 + ret = scsi_encap(sim, ccb); +#else + isc_session_t *sp = cam_sim_softc(sim); + + mtx_unlock(&sp->cam_mtx); + ret = scsi_encap(sim, ccb); + mtx_lock(&sp->cam_mtx); #endif - sp->flags &= ~ISC_FROZEN; + return ret; } void ic_lost_target(isc_session_t *sp, int target) { - struct isc_softc *isp = sp->isc; - debug_called(8); - sdebug(2, "target=%d", target); + sdebug(2, "lost target=%d", target); + if(sp->cam_path != NULL) { - mtx_lock(&isp->cam_mtx); + mtx_lock(&sp->cam_mtx); xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL); xpt_free_path(sp->cam_path); - mtx_unlock(&isp->cam_mtx); + mtx_unlock(&sp->cam_mtx); sp->cam_path = 0; // XXX } } static void -_scan_callback(struct cam_periph *periph, union ccb *ccb) +scan_callback(struct cam_periph *periph, union ccb *ccb) { isc_session_t *sp = (isc_session_t *)ccb->ccb_h.spriv_ptr0; @@ -106,63 +129,52 @@ free(ccb, M_TEMP); - if(sp->flags & ISC_FFPWAIT) { - sp->flags &= ~ISC_FFPWAIT; + if(sp->flags & ISC_SCANWAIT) { + sp->flags &= ~ISC_SCANWAIT; wakeup(sp); } } -static void -_scan_target(isc_session_t *sp, int target) +static int +ic_scan(isc_session_t *sp) { - union ccb *ccb; + union ccb *ccb; debug_called(8); - sdebug(2, "target=%d", target); + sdebug(2, "scanning sid=%d", sp->sid); if((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO)) == NULL) { xdebug("scan failed (can't allocate CCB)"); - return; + return ENOMEM; // XXX } - CAM_LOCK(sp->isc); + + sp->flags &= ~ISC_CAMDEVS; + sp->flags |= ISC_SCANWAIT; + + CAM_LOCK(sp); + if(xpt_create_path(&sp->cam_path, xpt_periph, cam_sim_path(sp->cam_sim), + 0, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xdebug("can't create cam path"); + CAM_UNLOCK(sp); + free(ccb, M_TEMP); + return ENODEV; // XXX + } xpt_setup_ccb(&ccb->ccb_h, sp->cam_path, 5/*priority (low)*/); ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = _scan_callback; + ccb->ccb_h.cbfcnp = scan_callback; ccb->crcn.flags = CAM_FLAG_NONE; ccb->ccb_h.spriv_ptr0 = sp; xpt_action(ccb); - CAM_UNLOCK(sp->isc); -} + CAM_UNLOCK(sp); -int -ic_fullfeature(struct cdev *dev) -{ - struct isc_softc *isp = dev->si_drv1; - isc_session_t *sp = (isc_session_t *)dev->si_drv2; - - debug_called(8); - sdebug(3, "dev=%d sc=%p", dev2unit(dev), isp); - - sp->flags &= ~ISC_FFPHASE; - sp->flags |= ISC_FFPWAIT; - - CAM_LOCK(isp); - if(xpt_create_path(&sp->cam_path, xpt_periph, cam_sim_path(sp->isc->cam_sim), - sp->sid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xdebug("can't create cam path"); - CAM_UNLOCK(isp); - return ENODEV; // XXX - } - CAM_UNLOCK(isp); - - _scan_target(sp, sp->sid); - - while(sp->flags & ISC_FFPWAIT) + while(sp->flags & ISC_SCANWAIT) tsleep(sp, PRIBIO, "ffp", 5*hz); // the timeout time should // be configurable + sdebug(2, "# of luns=%d", sp->target_nluns); + if(sp->target_nluns > 0) { - sp->flags |= ISC_FFPHASE; + sp->flags |= ISC_CAMDEVS; return 0; } @@ -170,110 +182,25 @@ } static void -_inq(struct cam_sim *sim, union ccb *ccb, int maxluns) -{ - struct ccb_pathinq *cpi = &ccb->cpi; - - debug_called(4); - - cpi->version_num = 1; /* XXX??? */ - cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_32; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = ISCSI_MAX_TARGETS - 1; - cpi->initiator_id = ISCSI_MAX_TARGETS; - cpi->max_lun = maxluns; - cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 3300; - strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN); - strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); - cpi->unit_number = cam_sim_unit(sim); - cpi->transport = XPORT_ISCSI; - cpi->transport_version = 0; - cpi->ccb_h.status = CAM_REQ_CMP; -} - -static __inline int -_scsi_encap(struct cam_sim *sim, union ccb *ccb) -{ - int ret; - -#if __FreeBSD_version < 700000 - ret = scsi_encap(sim, ccb); -#else - struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim); - - mtx_unlock(&isp->cam_mtx); - ret = scsi_encap(sim, ccb); - mtx_lock(&isp->cam_mtx); -#endif - return ret; -} - -static void ic_action(struct cam_sim *sim, union ccb *ccb) { + isc_session_t *sp = cam_sim_softc(sim); struct ccb_hdr *ccb_h = &ccb->ccb_h; - struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim); - isc_session_t *sp; debug_called(8); - if((ccb_h->target_id != CAM_TARGET_WILDCARD) && (ccb_h->target_id < MAX_SESSIONS)) - sp = isp->sessions[ccb_h->target_id]; - else - sp = NULL; - ccb_h->spriv_ptr0 = sp; - - debug(4, "func_code=0x%x flags=0x%x status=0x%x target=%d lun=%d retry_count=%d timeout=%d", + sdebug(4, "func_code=0x%x flags=0x%x status=0x%x target=%d lun=%d retry_count=%d timeout=%d", ccb_h->func_code, ccb->ccb_h.flags, ccb->ccb_h.status, ccb->ccb_h.target_id, ccb->ccb_h.target_lun, ccb->ccb_h.retry_count, ccb_h->timeout); - /* - | first quick check - */ + if(sp == NULL) { + xdebug("sp == NULL! cannot happen"); + return; + } switch(ccb_h->func_code) { - default: - // XXX: maybe check something else? - break; - - case XPT_SCSI_IO: - case XPT_RESET_DEV: - case XPT_GET_TRAN_SETTINGS: - case XPT_SET_TRAN_SETTINGS: - case XPT_CALC_GEOMETRY: - if(sp == NULL) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; -#if __FreeBSD_version < 700000 - XPT_DONE(isp, ccb); -#else - xpt_done(ccb); -#endif - return; - } - break; - case XPT_PATH_INQ: - case XPT_NOOP: - if(sp == NULL && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; -#if __FreeBSD_version < 700000 - XPT_DONE(isp, ccb); -#else - xpt_done(ccb); -#endif - debug(4, "status = CAM_DEV_NOT_THERE"); - return; - } - } - - switch(ccb_h->func_code) { - - case XPT_PATH_INQ: - _inq(sim, ccb, (sp? sp->opt.maxluns: ISCSI_MAX_LUNS) - 1); + _inq(sim, ccb); break; case XPT_RESET_BUS: // (can just be a stub that does nothing and completes) @@ -310,14 +237,35 @@ struct ccb_calc_geometry *ccg; ccg = &ccb->ccg; - debug(6, "XPT_CALC_GEOMETRY vsize=%jd bsize=%d", ccg->volume_size, ccg->block_size); + debug(4, "sid=%d target=%d lun=%d XPT_CALC_GEOMETRY vsize=%jd bsize=%d", + sp->sid, ccb->ccb_h.target_id, ccb->ccb_h.target_lun, + ccg->volume_size, ccg->block_size); if(ccg->block_size == 0 || (ccg->volume_size < ccg->block_size)) { // print error message ... /* XXX: what error is appropiate? */ break; - } else + } + else { + int lun, *off, boff; + + lun = ccb->ccb_h.target_lun; + if(lun > ISCSI_MAX_LUNS) { + // XXX: + xdebug("lun %d > ISCSI_MAX_LUNS!\n", lun); + lun %= ISCSI_MAX_LUNS; + } + off = &sp->target_lun[lun / (sizeof(int)*8)]; + boff = BIT(lun % (sizeof(int)*8)); + debug(4, "sp->target_nluns=%d *off=%x boff=%x", + sp->target_nluns, *off, boff); + + if((*off & boff) == 0) { + sp->target_nluns++; + *off |= boff; + } cam_calc_geometry(ccg, /*extended*/1); + } break; } @@ -327,7 +275,7 @@ break; } #if __FreeBSD_version < 700000 - XPT_DONE(isp, ccb); + XPT_DONE(sp, ccb); #else xpt_done(ccb); #endif @@ -337,102 +285,102 @@ static void ic_poll(struct cam_sim *sim) { - debug_called(8); + debug_called(4); } int ic_getCamVals(isc_session_t *sp, iscsi_cam_t *cp) { - int i; - debug_called(8); - if(sp && sp->isc->cam_sim) { - cp->path_id = cam_sim_path(sp->isc->cam_sim); - cp->target_id = sp->sid; - cp->target_nluns = sp->target_nluns; // XXX: -1? - for(i = 0; i < cp->target_nluns; i++) - cp->target_lun[i] = sp->target_lun[i]; + if(sp && sp->cam_sim) { + cp->path_id = cam_sim_path(sp->cam_sim); + cp->target_id = 0; + cp->target_nluns = ISCSI_MAX_LUNS; // XXX: -1? return 0; } return ENXIO; } void -ic_destroy(struct isc_softc *isp) +ic_destroy(isc_session_t *sp ) { debug_called(8); - CAM_LOCK(isp); // can't harm :-) + if(sp->cam_path != NULL) { + sdebug(2, "name=%s unit=%d", + cam_sim_name(sp->cam_sim), cam_sim_unit(sp->cam_sim)); + CAM_LOCK(sp); +#if 0 + xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL); +#else + xpt_async(XPT_RESET_BUS, sp->cam_path, NULL); +#endif + xpt_free_path(sp->cam_path); + xpt_bus_deregister(cam_sim_path(sp->cam_sim)); + cam_sim_free(sp->cam_sim, TRUE /*free_devq*/); - xpt_async(AC_LOST_DEVICE, isp->cam_path, NULL); - xpt_free_path(isp->cam_path); - - xpt_bus_deregister(cam_sim_path(isp->cam_sim)); - cam_sim_free(isp->cam_sim, TRUE /*free_devq*/); - - CAM_UNLOCK(isp); + CAM_UNLOCK(sp); + sdebug(2, "done"); + } } int -ic_init(struct isc_softc *isp) +ic_init(isc_session_t *sp) { struct cam_sim *sim; struct cam_devq *devq; - struct cam_path *path; + debug_called(8); + if((devq = cam_simq_alloc(256)) == NULL) return ENOMEM; #if __FreeBSD_version >= 700000 - mtx_init(&isp->cam_mtx, "isc-cam", NULL, MTX_DEF); + mtx_init(&sp->cam_mtx, "isc-cam", NULL, MTX_DEF); #else isp->cam_mtx = Giant; #endif - sim = cam_sim_alloc(ic_action, ic_poll, - "iscsi", isp, 0/*unit*/, + sim = cam_sim_alloc(ic_action, + ic_poll, + "iscsi", + sp, + sp->sid, // unit #if __FreeBSD_version >= 700000 - &isp->cam_mtx, + &sp->cam_mtx, #endif - 1/*max_dev_transactions*/, - 100/*max_tagged_dev_transactions*/, + 1, // max_dev_transactions + 0, // max_tagged_dev_transactions devq); if(sim == NULL) { cam_simq_free(devq); #if __FreeBSD_version >= 700000 - mtx_destroy(&isp->cam_mtx); + mtx_destroy(&sp->cam_mtx); #endif return ENXIO; } - CAM_LOCK(isp); + + CAM_LOCK(sp); if(xpt_bus_register(sim, #if __FreeBSD_version >= 700000 NULL, #endif - 0/*bus_number*/) != CAM_SUCCESS) - goto bad; + 0/*bus_number*/) != CAM_SUCCESS) { - if(xpt_create_path(&path, xpt_periph, cam_sim_path(sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_bus_deregister(cam_sim_path(sim)); - goto bad; + cam_sim_free(sim, /*free_devq*/TRUE); + CAM_UNLOCK(sp); +#if __FreeBSD_version >= 700000 + mtx_destroy(&sp->cam_mtx); +#endif + return ENXIO; } + sp->cam_sim = sim; + CAM_UNLOCK(sp); - CAM_UNLOCK(isp); + sdebug(1, "cam subsystem initialized"); - isp->cam_sim = sim; - isp->cam_path = path; + ic_scan(sp); - debug(2, "cam subsystem initialized"); // XXX: add dev ... - debug(4, "sim=%p path=%p", sim, path); return 0; - - bad: - cam_sim_free(sim, /*free_devq*/TRUE); - CAM_UNLOCK(isp); -#if __FreeBSD_version >= 700000 - mtx_destroy(&isp->cam_mtx); -#endif - return ENXIO; } Index: sys/dev/iscsi/initiator/iscsi.h =================================================================== --- sys/dev/iscsi/initiator/iscsi.h (revision 210555) +++ sys/dev/iscsi/initiator/iscsi.h (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * $FreeBSD$ */ /* - | $Id: iscsi.h,v 1.17 2006/12/01 09:10:17 danny Exp danny $ + | $Id: iscsi.h 743 2009-08-08 10:54:53Z danny $ */ #define TRUE 1 #define FALSE 0 @@ -37,11 +37,7 @@ #include #define ISCSIDEV "iscsi" - -#define ISCSI_MAX_TARGETS 4 //64 - -#define ISCSI_MAX_LUNS 4 - +#define ISCSI_MAX_TARGETS 64 /* | iSCSI commands */ @@ -422,13 +418,13 @@ */ typedef struct { union ipdu_u ipdu; + u_int hdr_dig; // header digest - ahs_t *ahs; + ahs_t *ahs_addr; u_int ahs_len; u_int ahs_size; // the allocated size - u_int hdr_dig; // header digest - u_char *ds; + u_char *ds_addr; u_int ds_len; u_int ds_size; // the allocated size u_int ds_dig; // data digest @@ -474,6 +470,7 @@ u_char tgtChapID; char *tgtChapDigest; char *iqn; + char *pidfile; } isc_opt_t; /* @@ -498,7 +495,6 @@ path_id_t path_id; target_id_t target_id; int target_nluns; - lun_id_t target_lun[ISCSI_MAX_LUNS]; } iscsi_cam_t; #define ISCSIGETCAM _IOR('i', 33, iscsi_cam_t) Index: sys/dev/iscsi/initiator/isc_soc.c =================================================================== --- sys/dev/iscsi/initiator/isc_soc.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_soc.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,10 +25,8 @@ * */ /* - | iSCSI - | $Id: isc_soc.c,v 1.26 2007/05/19 06:09:01 danny Exp danny $ + | $Id: isc_soc.c 998 2009-12-20 10:32:45Z danny $ */ - #include __FBSDID("$FreeBSD$"); @@ -66,9 +64,7 @@ #endif #ifdef USE_MBUF - static int ou_refcnt = 0; - /* | function for freeing external storage for mbuf */ @@ -79,7 +75,7 @@ if(pq->buf != NULL) { debug(3, "ou_refcnt=%d a=%p b=%p", ou_refcnt, a, pq->buf); - free(pq->buf, M_ISCSI); + free(pq->buf, M_ISCSIBUF); pq->buf = NULL; } } @@ -88,84 +84,96 @@ isc_sendPDU(isc_session_t *sp, pduq_t *pq) { struct mbuf *mh, **mp; - pdu_t *pp = &pq->pdu; - int len, error; + pdu_t *pp = &pq->pdu; + int len, error; debug_called(8); /* | mbuf for the iSCSI header */ MGETHDR(mh, M_TRYWAIT, MT_DATA); - mh->m_len = mh->m_pkthdr.len = sizeof(union ipdu_u); mh->m_pkthdr.rcvif = NULL; - MH_ALIGN(mh, sizeof(union ipdu_u)); - bcopy(&pp->ipdu, mh->m_data, sizeof(union ipdu_u)); mh->m_next = NULL; + mh->m_len = sizeof(union ipdu_u); - if(sp->hdrDigest) - pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0); + if(ISOK2DIG(sp->hdrDigest, pp)) { + pp->hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0); + mh->m_len += sizeof(pp->hdr_dig); + if(pp->ahs_len) { + debug(2, "ahs_len=%d", pp->ahs_len); + pp->hdr_dig = sp->hdrDigest(&pp->ahs_addr, pp->ahs_len, pp->hdr_dig); + } + debug(3, "pp->hdr_dig=%04x", htonl(pp->hdr_dig)); + } if(pp->ahs_len) { /* | Add any AHS to the iSCSI hdr mbuf - | XXX Assert: (mh->m_pkthdr.len + pp->ahs_len) < MHLEN */ - bcopy(pp->ahs, (mh->m_data + mh->m_len), pp->ahs_len); - mh->m_len += pp->ahs_len; - mh->m_pkthdr.len += pp->ahs_len; - - if(sp->hdrDigest) - pq->pdu.hdr_dig = sp->hdrDigest(&pp->ahs, pp->ahs_len, pq->pdu.hdr_dig); + if((mh->m_len + pp->ahs_len) < MHLEN) { + MH_ALIGN(mh, mh->m_len + pp->ahs_len); + bcopy(&pp->ipdu, mh->m_data, mh->m_len); + bcopy(pp->ahs_addr, mh->m_data + mh->m_len, pp->ahs_len); + mh->m_len += pp->ahs_len; + } + else + panic("len AHS=%d too big, not impleneted yet", pp->ahs_len); } - if(sp->hdrDigest) { - debug(2, "hdr_dig=%x", pq->pdu.hdr_dig); - /* - | Add header digest to the iSCSI hdr mbuf - | XXX Assert: (mh->m_pkthdr.len + 4) < MHLEN - */ - bcopy(&pp->hdr_dig, (mh->m_data + mh->m_len), sizeof(int)); - mh->m_len += sizeof(int); - mh->m_pkthdr.len += sizeof(int); + else { + MH_ALIGN(mh, mh->m_len); + bcopy(&pp->ipdu, mh->m_data, mh->m_len); } + mh->m_pkthdr.len = mh->m_len; mp = &mh->m_next; - if(pq->pdu.ds) { - struct mbuf *md; - int off = 0; + if(pp->ds_len && pq->pdu.ds_addr) { + struct mbuf *md; + int off = 0; len = pp->ds_len; - while(len & 03) // the specs say it must be int alligned - len++; while(len > 0) { - int l; - + int l; + MGET(md, M_TRYWAIT, MT_DATA); md->m_ext.ref_cnt = &ou_refcnt; - l = min(MCLBYTES, len); - debug(5, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l); - MEXTADD(md, pp->ds + off, l, ext_free, pp->ds + off, pq, 0, EXT_EXTREF); - md->m_len = l; - md->m_next = NULL; - mh->m_pkthdr.len += l; - *mp = md; - mp = &md->m_next; - len -= l; - off += l; - } + l = min(MCLBYTES, len); + debug(4, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l); + MEXTADD(md, pp->ds_addr + off, l, ext_free, +#if __FreeBSD_version >= 800000 + pp->ds_addr + off, +#endif + pq, 0, EXT_EXTREF); + md->m_len = l; + md->m_next = NULL; + mh->m_pkthdr.len += l; + *mp = md; + mp = &md->m_next; + len -= l; + off += l; + } + if(((pp->ds_len & 03) != 0) || ISOK2DIG(sp->dataDigest, pp)) { + MGET(md, M_TRYWAIT, MT_DATA); + if(pp->ds_len & 03) + len = 4 - (pp->ds_len & 03); + else + len = 0; + md->m_len = len; + if(ISOK2DIG(sp->dataDigest, pp)) + md->m_len += sizeof(pp->ds_dig); + MH_ALIGN(md, md->m_len); + if(ISOK2DIG(sp->dataDigest, pp)) { + pp->ds_dig = sp->dataDigest(pp->ds_addr, pp->ds_len, 0); + if(len) { + bzero(md->m_data, len); // RFC says SHOULD be 0 + pp->ds_dig = sp->dataDigest(md->m_data, len, pp->ds_dig); + } + bcopy(&pp->ds_dig, md->m_data+len, sizeof(pp->ds_dig)); + } + md->m_next = NULL; + mh->m_pkthdr.len += md->m_len; + *mp = md; + } } - if(sp->dataDigest) { - struct mbuf *me; - - pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0); - - MGET(me, M_TRYWAIT, MT_DATA); - me->m_len = sizeof(int); - MH_ALIGN(mh, sizeof(int)); - bcopy(&pp->ds_dig, me->m_data, sizeof(int)); - me->m_next = NULL; - mh->m_pkthdr.len += sizeof(int); - *mp = me; - } if((error = sosend(sp->soc, NULL, NULL, mh, 0, 0, sp->td)) != 0) { - sdebug(3, "error=%d", error); + sdebug(2, "error=%d", error); return error; } sp->stats.nsent++; @@ -191,39 +199,46 @@ iv->iov_base = &pp->ipdu; iv->iov_len = sizeof(union ipdu_u); - uio->uio_resid = pq->len; + uio->uio_resid = iv->iov_len; iv++; - if(sp->hdrDigest) + if(ISOK2DIG(sp->hdrDigest, pp)) pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0); if(pp->ahs_len) { - iv->iov_base = pp->ahs; + iv->iov_base = pp->ahs_addr; iv->iov_len = pp->ahs_len; + uio->uio_resid += iv->iov_len; iv++; - - if(sp->hdrDigest) - pq->pdu.hdr_dig = sp->hdrDigest(&pp->ahs, pp->ahs_len, pq->pdu.hdr_dig); + if(ISOK2DIG(sp->hdrDigest, pp)) + pp->hdr_dig = sp->hdrDigest(&pp->ahs_addr, pp->ahs_len, pp->hdr_dig); } - if(sp->hdrDigest) { - debug(2, "hdr_dig=%x", pq->pdu.hdr_dig); + if(ISOK2DIG(sp->hdrDigest, pp)) { + debug(3, "hdr_dig=%04x", htonl(pp->hdr_dig)); iv->iov_base = &pp->hdr_dig; iv->iov_len = sizeof(int); + uio->uio_resid += iv->iov_len ; iv++; } - if(pq->pdu.ds) { - iv->iov_base = pp->ds; + if(pq->pdu.ds_addr && pp->ds_len) { + iv->iov_base = pp->ds_addr; iv->iov_len = pp->ds_len; while(iv->iov_len & 03) // the specs say it must be int alligned iv->iov_len++; + uio->uio_resid += iv->iov_len ; iv++; + if(ISOK2DIG(sp->dataDigest, pp)) { + pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0); + iv->iov_base = &pp->ds_dig; + iv->iov_len = sizeof(pp->ds_dig); + uio->uio_resid += iv->iov_len ; + iv++; + } } - if(sp->dataDigest) { - pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0); - iv->iov_base = &pp->ds_dig; - iv->iov_len = sizeof(int); - iv++; - } - uio->uio_iovcnt = iv - pq->iov; - sdebug(5, "opcode=%x iovcnt=%d uio_resid=%d itt=%x", + uio->uio_iovcnt = iv - pq->iov; + sdebug(4, "pq->len=%d uio->uio_resid=%d uio->uio_iovcnt=%d", pq->len, + uio->uio_resid, + uio->uio_iovcnt); + + sdebug(4, "opcode=%x iovcnt=%d uio_resid=%d itt=%x", pp->ipdu.bhs.opcode, uio->uio_iovcnt, uio->uio_resid, ntohl(pp->ipdu.bhs.itt)); sdebug(5, "sp=%p sp->soc=%p uio=%p sp->td=%p", @@ -244,12 +259,12 @@ | XXX: untested code */ sdebug(1, "uio->uio_resid=%d uio->uio_iovcnt=%d", - uio->uio_resid, uio->uio_iovcnt); + uio->uio_resid, uio->uio_iovcnt); iv = uio->uio_iov; len -= uio->uio_resid; while(uio->uio_iovcnt > 0) { if(iv->iov_len > len) { - caddr_t bp = (caddr_t)iv->iov_base; + caddr_t bp = (caddr_t)iv->iov_base; iv->iov_len -= len; iv->iov_base = (void *)&bp[len]; @@ -265,7 +280,6 @@ if(error == 0) { sp->stats.nsent++; getbintime(&sp->stats.t_sent); - } return error; @@ -322,159 +336,197 @@ error = soreceive(sp->soc, NULL, uio, 0, 0, &flags); if(error) - debug(2, "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd", + debug(2, +#if __FreeBSD_version > 800000 + "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd", +#else + "error=%d so_error=%d uio->uio_resid=%d iov.iov_len=%zd", +#endif error, sp->soc->so_error, uio->uio_resid, iov->iov_len); if(!error && (uio->uio_resid > 0)) { error = EPIPE; // was EAGAIN - debug(2, "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd so_state=%x", + debug(2, +#if __FreeBSD_version > 800000 + "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd so_state=%x", +#else + "error=%d so_error=%d uio->uio_resid=%d iov.iov_len=%zd so_state=%x", +#endif error, sp->soc->so_error, uio->uio_resid, iov->iov_len, sp->soc->so_state); } - return error; } /* - | so_recv gets called when there is at least - | an iSCSI header in the queue + | so_recv gets called when + | an iSCSI header has been received. + | Note: the designers had no intentions + | in making programmer's life easy. */ static int so_recv(isc_session_t *sp, pduq_t *pq) { - struct socket *so = sp->soc; sn_t *sn = &sp->sn; struct uio *uio = &pq->uio; - pdu_t *pp; + pdu_t *pp = &pq->pdu; + bhs_t *bhs = &pp->ipdu.bhs; + struct iovec *iov = pq->iov; int error; - size_t n, len; - bhs_t *bhs; + u_int len; u_int max, exp; + int flags = MSG_WAITALL; debug_called(8); /* | now calculate how much data should be in the buffer - | NOTE: digest is not verified/calculated - yet */ - pp = &pq->pdu; - bhs = &pp->ipdu.bhs; - + uio->uio_iov = iov; + uio->uio_iovcnt = 0; len = 0; if(bhs->AHSLength) { + debug(2, "bhs->AHSLength=%d", bhs->AHSLength); pp->ahs_len = bhs->AHSLength * 4; len += pp->ahs_len; + pp->ahs_addr = malloc(pp->ahs_len, M_TEMP, M_WAITOK); // XXX: could get stuck here + iov->iov_base = pp->ahs_addr; + iov->iov_len = pp->ahs_len; + uio->uio_iovcnt++; + iov++; } - if(sp->hdrDigest) - len += 4; + if(ISOK2DIG(sp->hdrDigest, pp)) { + len += sizeof(pp->hdr_dig); + iov->iov_base = &pp->hdr_dig; + iov->iov_len = sizeof(pp->hdr_dig); + uio->uio_iovcnt++; + } + if(len) { + uio->uio_rw = UIO_READ; + uio->uio_segflg = UIO_SYSSPACE; + uio->uio_resid = len; + uio->uio_td = sp->td; // why ... + error = soreceive(sp->soc, NULL, uio, NULL, NULL, &flags); + //if(error == EAGAIN) + // XXX: this needs work! it hangs iscontrol + if(error || uio->uio_resid) { + debug(2, +#if __FreeBSD_version > 800000 + "len=%d error=%d uio->uio_resid=%zd", +#else + "len=%d error=%d uio->uio_resid=%d", +#endif + len, error, uio->uio_resid); + goto out; + } + if(ISOK2DIG(sp->hdrDigest, pp)) { + bhs_t *bhs; + u_int digest; + + bhs = (bhs_t *)&pp->ipdu; + digest = sp->hdrDigest(bhs, sizeof(bhs_t), 0); + if(pp->ahs_len) + digest = sp->hdrDigest(pp->ahs_addr, pp->ahs_len, digest); + if(pp->hdr_dig != digest) { + debug(2, "bad header digest: received=%x calculated=%x", pp->hdr_dig, digest); + // XXX: now what? + error = EIO; + goto out; + } + } + if(pp->ahs_len) { + debug(2, "ahs len=%x type=%x spec=%x", + pp->ahs_addr->len, pp->ahs_addr->type, pp->ahs_addr->spec); + // XXX: till I figure out what to do with this + free(pp->ahs_addr, M_TEMP); + } + pq->len += len; // XXX: who needs this? + bzero(uio, sizeof(struct uio)); + len = 0; + } + if(bhs->DSLength) { - n = bhs->DSLength; + len = bhs->DSLength; #if BYTE_ORDER == LITTLE_ENDIAN - pp->ds_len = ((n & 0x00ff0000) >> 16) - | (n & 0x0000ff00) - | ((n & 0x000000ff) << 16); -#else - pp->ds_len = n; + len = ((len & 0x00ff0000) >> 16) + | (len & 0x0000ff00) + | ((len & 0x000000ff) << 16); #endif - len += pp->ds_len; + pp->ds_len = len; + if((sp->opt.maxRecvDataSegmentLength > 0) && (len > sp->opt.maxRecvDataSegmentLength)) { + xdebug("impossible PDU length(%d) opt.maxRecvDataSegmentLength=%d", + len, sp->opt.maxRecvDataSegmentLength); + log(LOG_ERR, + "so_recv: impossible PDU length(%d) from iSCSI %s/%s\n", + len, sp->opt.targetAddress, sp->opt.targetName); + /* + | XXX: this will really screwup the stream. + | should clear up the buffer till a valid header + | is found, or just close connection ... + | should read the RFC. + */ + error = E2BIG; + goto out; + } while(len & 03) len++; - if(sp->dataDigest) + if(ISOK2DIG(sp->dataDigest, pp)) len += 4; - } - - if((sp->opt.maxRecvDataSegmentLength > 0) && (len > sp->opt.maxRecvDataSegmentLength)) { -#if 0 - xdebug("impossible PDU length(%d) opt.maxRecvDataSegmentLength=%d", - len, sp->opt.maxRecvDataSegmentLength); - // deep trouble here, probably all we can do is - // force a disconnect, XXX: check RFC ... - log(LOG_ERR, - "so_recv: impossible PDU length(%ld) from iSCSI %s/%s\n", - len, sp->opt.targetAddress, sp->opt.targetName); -#endif - /* - | XXX: this will really screwup the stream. - | should clear up the buffer till a valid header - | is found, or just close connection ... - | should read the RFC. - */ - error = E2BIG; - goto out; - } - if(len) { - int flags = MSG_WAITALL; - struct mbuf **mp; - - mp = &pq->mp; - uio->uio_resid = len; - uio->uio_td = curthread; // why ... - if(sp->douio) { - // it's more efficient to use mbufs -- why? - if(bhs->opcode == ISCSI_READ_DATA) { - pduq_t *opq; - - opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1); - if(opq != NULL) { - union ccb *ccb = opq->ccb; - struct ccb_scsiio *csio = &ccb->csio; - pdu_t *opp = &opq->pdu; - scsi_req_t *cmd = &opp->ipdu.scsi_req; - data_in_t *rcmd = &pq->pdu.ipdu.data_in; - bhs_t *bhp = &opp->ipdu.bhs; - int r; - - if(bhp->opcode == ISCSI_SCSI_CMD - && cmd->R - && (ntohl(cmd->edtlen) >= pq->pdu.ds_len)) { - struct iovec *iov = pq->iov; - iov->iov_base = csio->data_ptr + ntohl(rcmd->bo); - iov->iov_len = pq->pdu.ds_len; - - uio->uio_rw = UIO_READ; - uio->uio_segflg = UIO_SYSSPACE; - uio->uio_iov = iov; - uio->uio_iovcnt = 1; - if(len > pq->pdu.ds_len) { - pq->iov[1].iov_base = &r; - pq->iov[1].iov_len = len - pq->pdu.ds_len; - uio->uio_iovcnt++; - } - mp = NULL; - - sdebug(4, "uio_resid=0x%zx itt=0x%x bp=%p bo=%x len=%x/%x", - uio->uio_resid, - ntohl(pq->pdu.ipdu.bhs.itt), - csio->data_ptr, ntohl(rcmd->bo), ntohl(cmd->edtlen), pq->pdu.ds_len); - } - } - } - } - error = soreceive(so, NULL, uio, mp, NULL, &flags); + uio->uio_td = sp->td; // why ... + pq->len += len; // XXX: do we need this? + error = soreceive(sp->soc, NULL, uio, &pq->mp, NULL, &flags); //if(error == EAGAIN) // XXX: this needs work! it hangs iscontrol if(error || uio->uio_resid) goto out; + if(ISOK2DIG(sp->dataDigest, pp)) { + struct mbuf *m; + u_int digest, ds_len, cnt; + + // get the received digest + m_copydata(pq->mp, + len - sizeof(pp->ds_dig), + sizeof(pp->ds_dig), + (caddr_t)&pp->ds_dig); + // calculate all mbufs + digest = 0; + ds_len = len - sizeof(pp->ds_dig); + for(m = pq->mp; m != NULL; m = m->m_next) { + cnt = MIN(ds_len, m->m_len); + digest = sp->dataDigest(mtod(m, char *), cnt, digest); + ds_len -= cnt; + if(ds_len == 0) + break; + } + if(digest != pp->ds_dig) { + sdebug(1, "bad data digest: received=%x calculated=%x", pp->ds_dig, digest); + error = EIO; // XXX: find a better error + goto out; + } + KASSERT(ds_len == 0, ("ds_len not zero")); + } } - pq->len += len; sdebug(6, "len=%d] opcode=0x%x ahs_len=0x%x ds_len=0x%x", pq->len, bhs->opcode, pp->ahs_len, pp->ds_len); max = ntohl(bhs->MaxCmdSN); exp = ntohl(bhs->ExpStSN); - if(max < exp - 1 && max > exp - _MAXINCR) { sdebug(2, "bad cmd window size"); error = EIO; // XXX: for now; goto out; // error } - if(SNA_GT(max, sn->maxCmd)) sn->maxCmd = max; - if(SNA_GT(exp, sn->expCmd)) sn->expCmd = exp; + /* + | remove from the holding queue packets + | that have been acked and don't need + | further processing. + */ + i_acked_hld(sp, NULL); sp->cws = sn->maxCmd - sn->expCmd + 1; @@ -482,6 +534,10 @@ out: // XXX: need some work here + if(pp->ahs_len) { + // XXX: till I figure out what to do with this + free(pp->ahs_addr, M_TEMP); + } xdebug("have a problem, error=%d", error); pdu_free(sp->isc, pq); if(!error && uio->uio_resid > 0) @@ -510,8 +566,8 @@ */ pq = pdu_alloc(sp->isc, M_NOWAIT); if(pq == NULL) { // XXX: might cause a deadlock ... - debug(3, "out of pdus, wait"); - pq = pdu_alloc(sp->isc, M_NOWAIT); // OK to WAIT + debug(2, "out of pdus, wait"); + pq = pdu_alloc(sp->isc, M_WAITOK); // OK to WAIT } pq->pdu.ipdu.bhs = sp->bhs; pq->len = sizeof(bhs_t); // so far only the header was read @@ -536,7 +592,7 @@ | in packets from the target. */ static void -isc_soc(void *vp) +isc_in(void *vp) { isc_session_t *sp = (isc_session_t *)vp; struct socket *so = sp->soc; @@ -545,9 +601,6 @@ debug_called(8); sp->flags |= ISC_CON_RUNNING; - if(sp->cam_path) - ic_release(sp); - error = 0; while((sp->flags & (ISC_CON_RUN | ISC_LINK_UP)) == (ISC_CON_RUN | ISC_LINK_UP)) { // XXX: hunting ... @@ -559,7 +612,7 @@ if(error == 0) { mtx_lock(&sp->io_mtx); if(sp->flags & ISC_OWAITING) { - wakeup(&sp->flags); + wakeup(&sp->flags); } mtx_unlock(&sp->io_mtx); } else if(error == EPIPE) { @@ -594,8 +647,11 @@ mtx_unlock(&sp->io_mtx); sdebug(2, "dropped ISC_CON_RUNNING"); - +#if __FreeBSD_version >= 800000 kproc_exit(0); +#else + kthread_exit(0); +#endif } void @@ -621,7 +677,6 @@ } mtx_unlock(&sp->io_mtx); - if(sp->fp != NULL) fdrop(sp->fp, sp->td); fputsock(sp->soc); @@ -637,6 +692,10 @@ debug_called(8); sp->flags |= ISC_CON_RUN | ISC_LINK_UP; - - kproc_create(isc_soc, sp, &sp->soc_proc, 0, 0, "iscsi%d", sp->sid); +#if __FreeBSD_version >= 800000 + kproc_create +#else + kthread_create +#endif + (isc_in, sp, &sp->soc_proc, 0, 0, "isc_in %d", sp->sid); } Index: sys/dev/iscsi/initiator/iscsi_subr.c =================================================================== --- sys/dev/iscsi/initiator/iscsi_subr.c (revision 210555) +++ sys/dev/iscsi/initiator/iscsi_subr.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ * */ /* - | $Id: iscsi_subr.c,v 1.17 2006/11/26 14:50:43 danny Exp danny $ + | $Id: iscsi_subr.c 743 2009-08-08 10:54:53Z danny $ */ #include @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -122,7 +123,7 @@ bs = MIN(bs, bleft); wpq->pdu.ds_len = bs; - wpq->pdu.ds = bp; + wpq->pdu.ds_addr = bp; error = isc_qout(sp, wpq); sdebug(6, "bs=%x bo=%x bp=%p dsn=%x error=%d", bs, bo, bp, dsn, error); @@ -188,16 +189,16 @@ | Some information is from SAM draft. */ static void -_scsi_done(struct isc_softc *isp, u_int response, u_int status, union ccb *ccb, pduq_t *pq) +_scsi_done(isc_session_t *sp, u_int response, u_int status, union ccb *ccb, pduq_t *pq) { struct ccb_hdr *ccb_h = &ccb->ccb_h; debug_called(8); if(status || response) { - debug(3, "response=%x status=%x ccb=%p pq=%p", response, status, ccb, pq); + sdebug(3, "response=%x status=%x ccb=%p pq=%p", response, status, ccb, pq); if(pq != NULL) - debug(3, "mp=%p buf=%p len=%d", pq->mp, pq->buf, pq->len); + sdebug(3, "mp=%p buf=%p len=%d", pq->mp, pq->buf, pq->len); } ccb_h->status = 0; switch(response) { @@ -241,9 +242,9 @@ ccb_h->status = CAM_REQ_CMP_ERR; //CAM_REQ_ABORTED; break; } - debug(5, "ccb_h->status=%x", ccb_h->status); + sdebug(5, "ccb_h->status=%x", ccb_h->status); - XPT_DONE(isp, ccb); + XPT_DONE(sp, ccb); } /* @@ -256,16 +257,17 @@ u_int i, n, last; debug_called(8); - last = -1; - i = 0; + i = last = 0; sp->flags |= ISC_HOLD; while((pq = i_dqueue_hld(sp)) != NULL) { i++; - _scsi_done(sp->isc, 0, 0x28, pq->ccb, NULL); - n = ntohl(pq->pdu.ipdu.bhs.CmdSN); - if(last > n) - last = n; - sdebug(2, "last=%x n=%x", last, n); + if(pq->ccb != NULL) { + _scsi_done(sp, 0, 0x28, pq->ccb, NULL); + n = ntohl(pq->pdu.ipdu.bhs.CmdSN); + if(last==0 || (last > n)) + last = n; + sdebug(2, "last=%x n=%x", last, n); + } pdu_free(sp->isc, pq); } sp->flags &= ~ISC_HOLD; @@ -316,14 +318,22 @@ TAILQ_FOREACH_SAFE(pq, &sp->hld, pq_link, pqtmp) { sdebug(3, "hld pq=%p", pq); if(pq->ccb) - _scsi_done(sp->isc, 1, 0x40, pq->ccb, NULL); + _scsi_done(sp, 1, 0x40, pq->ccb, NULL); TAILQ_REMOVE(&sp->hld, pq, pq_link); + if(pq->buf) { + free(pq->buf, M_ISCSIBUF); + pq->buf = NULL; + } pdu_free(sp->isc, pq); } while((pq = i_dqueue_snd(sp, BIT(0)|BIT(1)|BIT(2))) != NULL) { sdebug(3, "pq=%p", pq); if(pq->ccb) - _scsi_done(sp->isc, 1, 0x40, pq->ccb, NULL); + _scsi_done(sp, 1, 0x40, pq->ccb, NULL); + if(pq->buf) { + free(pq->buf, M_ISCSIBUF); + pq->buf = NULL; + } pdu_free(sp->isc, pq); } @@ -338,7 +348,7 @@ debug_called(8); - _scsi_done(sp->isc, cmd->response, cmd->status, opq->ccb, pq); + _scsi_done(sp, cmd->response, cmd->status, opq->ccb, pq); pdu_free(sp->isc, opq); } @@ -394,7 +404,7 @@ debug_called(8); //XXX: check RFC 10.17.1 (page 176) ccb->ccb_h.status = CAM_REQ_ABORTED; - XPT_DONE(sp->isc, ccb); + XPT_DONE(sp, ccb); pdu_free(sp->isc, opq); } @@ -405,10 +415,8 @@ static int dwl(isc_session_t *sp, int lun, u_char *lp) { - int i; - debug_called(8); - + sdebug(4, "lun=%d", lun); /* | mapping LUN to iSCSI LUN | check the SAM-2 specs @@ -429,14 +437,6 @@ return -1; } - for(i = 0; i < sp->target_nluns; i++) - if(sp->target_lun[i] == lun) - return 0; - if(sp->target_nluns < ISCSI_MAX_LUNS) - sp->target_lun[sp->target_nluns++] = lun; - - sdebug(3, "nluns=%d lun=%d", sp->target_nluns, lun); - return 0; } @@ -446,8 +446,7 @@ int scsi_encap(struct cam_sim *sim, union ccb *ccb) { - struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim); - isc_session_t *sp; + isc_session_t *sp = cam_sim_softc(sim); struct ccb_scsiio *csio = &ccb->csio; struct ccb_hdr *ccb_h = &ccb->ccb_h; pduq_t *pq; @@ -458,33 +457,19 @@ debug(4, "ccb->sp=%p", ccb_h->spriv_ptr0); sp = ccb_h->spriv_ptr0; - if((pq = pdu_alloc(isp, M_NOWAIT)) == NULL) { + if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) { debug(2, "ccb->sp=%p", ccb_h->spriv_ptr0); sdebug(1, "pdu_alloc failed sc->npdu_max=%d npdu_alloc=%d", sp->isc->npdu_max, sp->isc->npdu_alloc); while((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) { - sdebug(3, "waiting..."); + sdebug(2, "waiting..."); #if __FreeBSD_version >= 700000 pause("isc_encap", 5*hz); #else tsleep(sp->isc, 0, "isc_encap", 5*hz); #endif } -#if 0 - sdebug(3, "freezing"); - ccb->ccb_h.status = CAM_REQUEUE_REQ; - ic_freeze(sp); - return 0; -#endif } - -#if 0 - if((sp->flags & ISC_FFPHASE) == 0) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; // CAM_NO_NEXUS; - sdebug(3, "no active session with target %d", ccb_h->target_id); - goto bad; - } -#endif cmd = &pq->pdu.ipdu.scsi_req; cmd->opcode = ISCSI_SCSI_CMD; cmd->F = 1; @@ -493,8 +478,8 @@ */ switch(csio->tag_action) { case MSG_SIMPLE_Q_TAG: cmd->attr = iSCSI_TASK_SIMPLE; break; - case MSG_HEAD_OF_Q_TAG: cmd->attr = iSCSI_TASK_ORDER; break; - case MSG_ORDERED_Q_TAG: cmd->attr = iSCSI_TASK_HOFQ; break; + case MSG_HEAD_OF_Q_TAG: cmd->attr = iSCSI_TASK_HOFQ; break; + case MSG_ORDERED_Q_TAG: cmd->attr = iSCSI_TASK_ORDER; break; case MSG_ACA_TASK: cmd->attr = iSCSI_TASK_ACA; break; } @@ -532,7 +517,8 @@ return 1; invalid: ccb->ccb_h.status = CAM_REQ_INVALID; - pdu_free(isp, pq); + pdu_free(sp->isc, pq); + return 0; } @@ -573,16 +559,16 @@ csio->data_ptr, bp? mtod(pq->mp, caddr_t): 0, ntohl(cmd->edtlen), pq->pdu.ds_len, pq->mp); if(ntohl(cmd->edtlen) >= pq->pdu.ds_len) { - int offset, len = pq->pdu.ds_len; + int offset, len = pq->pdu.ds_len; if(pq->mp != NULL) { - caddr_t dp; + caddr_t dp; - offset = ntohl(rcmd->bo); - dp = csio->data_ptr + offset; - i_mbufcopy(pq->mp, dp, len); + offset = ntohl(rcmd->bo); + dp = csio->data_ptr + offset; + i_mbufcopy(pq->mp, dp, len); + } } - } else { xdebug("edtlen=%d < ds_len=%d", ntohl(cmd->edtlen), pq->pdu.ds_len); @@ -592,7 +578,7 @@ /* | contains also the SCSI Status */ - _scsi_done(sp->isc, 0, rcmd->status, opq->ccb, NULL); + _scsi_done(sp, 0, rcmd->status, opq->ccb, NULL); return 0; } else return 1; Index: sys/dev/iscsi/initiator/iscsivar.h =================================================================== --- sys/dev/iscsi/initiator/iscsivar.h (revision 210555) +++ sys/dev/iscsi/initiator/iscsivar.h (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,9 +25,18 @@ * * $FreeBSD$ */ + /* - | $Id: iscsivar.h,v 1.30 2007/04/22 10:12:11 danny Exp danny $ + | $Id: iscsivar.h 743 2009-08-08 10:54:53Z danny $ */ +#define ISCSI_MAX_LUNS 128 // don't touch this +#if ISCSI_MAX_LUNS > 8 +/* + | for this to work + | sysctl kern.cam.cam_srch_hi=1 + */ +#endif + #ifndef ISCSI_INITIATOR_DEBUG #define ISCSI_INITIATOR_DEBUG 1 #endif @@ -48,13 +57,17 @@ #define xdebug(fmt, args...) printf(">>> %s: " fmt "\n", __func__ , ##args) -#define MAX_SESSIONS ISCSI_MAX_TARGETS +#define MAX_SESSIONS ISCSI_MAX_TARGETS +#define MAX_PDUS (MAX_SESSIONS*256) // XXX: at the moment this is arbitrary typedef uint32_t digest_t(const void *, int len, uint32_t ocrc); MALLOC_DECLARE(M_ISCSI); +MALLOC_DECLARE(M_ISCSIBUF); MALLOC_DECLARE(M_PDU); +#define ISOK2DIG(dig, pp) ((dig != NULL) && ((pp->ipdu.bhs.opcode & 0x1f) != ISCSI_LOGIN_CMD)) + #ifndef BIT #define BIT(n) (1 <<(n)) #endif @@ -69,16 +82,16 @@ #define ISC_OQNOTEMPTY BIT(6) #define ISC_OWAITING BIT(7) #define ISC_FFPHASE BIT(8) -#define ISC_FFPWAIT BIT(9) -#define ISC_MEMWAIT BIT(10) -#define ISC_SIGNALED BIT(11) -#define ISC_FROZEN BIT(12) -#define ISC_STALLED BIT(13) +#define ISC_CAMDEVS BIT(9) +#define ISC_SCANWAIT BIT(10) -#define ISC_HOLD BIT(14) -#define ISC_HOLDED BIT(15) +#define ISC_MEMWAIT BIT(11) +#define ISC_SIGNALED BIT(12) +#define ISC_HOLD BIT(15) +#define ISC_HOLDED BIT(16) + #define ISC_SHUTDOWN BIT(31) /* @@ -116,9 +129,7 @@ struct proc *proc; // the userland process int signal; - struct proc *soc_proc; - struct proc *stp; // the sm thread struct isc_softc *isc; @@ -127,16 +138,13 @@ digest_t *dataDigest; // the digest alg. if any int sid; // Session ID - int targetid; -// int cid; // Connection ID -// int tsih; // target session identifier handle sn_t sn; // sequence number stuff; int cws; // current window size int target_nluns; // this and target_lun are // hopefully temporal till I // figure out a better way. - lun_id_t target_lun[ISCSI_MAX_LUNS]; + int target_lun[ISCSI_MAX_LUNS/(sizeof(int)*8) + 1]; struct mtx rsp_mtx; struct mtx rsv_mtx; @@ -150,17 +158,19 @@ queue_t wsnd; queue_t hld; - /* - | negotiable values - */ - isc_opt_t opt; + isc_opt_t opt; // negotiable values struct i_stats stats; - struct cam_path *cam_path; bhs_t bhs; struct uio uio; struct iovec iov; /* + | cam stuff + */ + struct cam_sim *cam_sim; + struct cam_path *cam_path; + struct mtx cam_mtx; + /* | sysctl stuff */ struct sysctl_ctx_list clist; @@ -180,34 +190,30 @@ struct iovec iov[5]; // XXX: careful ... struct mbuf *mp; struct bintime ts; - queue_t *pduq; + queue_t *pduq; } pduq_t; - +/* + */ struct isc_softc { - //int state; + struct mtx isc_mtx; + TAILQ_HEAD(,isc_session) isc_sess; + int nsess; struct cdev *dev; - eventhandler_tag eh; char isid[6]; // Initiator Session ID (48 bits) - struct mtx mtx; + struct unrhdr *unit; + struct sx unit_sx; - int nsess; - TAILQ_HEAD(,isc_session) isc_sess; - isc_session_t *sessions[MAX_SESSIONS]; + struct mtx pdu_mtx; + uma_zone_t pdu_zone; // pool of free pdu's + TAILQ_HEAD(,pduq) freepdu; - struct mtx pdu_mtx; #ifdef ISCSI_INITIATOR_DEBUG - int npdu_alloc, npdu_max; // for instrumentation + int npdu_alloc, npdu_max; // for instrumentation #endif -#define MAX_PDUS (MAX_SESSIONS*256) // XXX: at the moment this is arbitrary - uma_zone_t pdu_zone; // pool of free pdu's - TAILQ_HEAD(,pduq) freepdu; +#ifdef DO_EVENTHANDLER + eventhandler_tag eh; +#endif /* - | cam stuff - */ - struct cam_sim *cam_sim; - struct cam_path *cam_path; - struct mtx cam_mtx; - /* | sysctl stuff */ struct sysctl_ctx_list clist; @@ -231,14 +237,14 @@ int i_setopt(isc_session_t *sp, isc_opt_t *opt); void i_freeopt(isc_opt_t *opt); -int ic_init(struct isc_softc *sc); -void ic_destroy(struct isc_softc *sc); -int ic_fullfeature(struct cdev *dev); +int ic_init(isc_session_t *sp); +void ic_destroy(isc_session_t *sp); void ic_lost_target(isc_session_t *sp, int target); int ic_getCamVals(isc_session_t *sp, iscsi_cam_t *cp); void ism_recv(isc_session_t *sp, pduq_t *pq); int ism_start(isc_session_t *sp); +void ism_restart(isc_session_t *sp); void ism_stop(isc_session_t *sp); int scsi_encap(struct cam_sim *sim, union ccb *ccb); @@ -250,9 +256,6 @@ void iscsi_cleanup(isc_session_t *sp); int iscsi_requeue(isc_session_t *sp); -void ic_freeze(isc_session_t *sp); -void ic_release(isc_session_t *sp); - // Serial Number Arithmetic #define _MAXINCR 0x7FFFFFFF // 2 ^ 31 - 1 #define SNA_GT(i1, i2) ((i1 != i2) && (\ @@ -269,7 +272,7 @@ #define CAM_ULOCK(arg) static __inline void -XPT_DONE(struct isc_softc *isp, union ccb *ccb) +XPT_DONE(isc_session_t *sp, union ccb *ccb) { mtx_lock(&Giant); xpt_done(ccb); @@ -280,11 +283,11 @@ #define CAM_UNLOCK(arg) mtx_unlock(&arg->cam_mtx) static __inline void -XPT_DONE(struct isc_softc *isp, union ccb *ccb) +XPT_DONE(isc_session_t *sp, union ccb *ccb) { - CAM_LOCK(isp); + CAM_LOCK(sp); xpt_done(ccb); - CAM_UNLOCK(isp); + CAM_UNLOCK(sp); } #else //__FreeBSD_version >= 600000 @@ -332,7 +335,7 @@ m_freem(pq->mp); #ifdef NO_USE_MBUF if(pq->buf != NULL) - free(pq->buf, M_ISCSI); + free(pq->buf, M_ISCSIBUF); #endif mtx_lock(&isc->pdu_mtx); TAILQ_INSERT_TAIL(&isc->freepdu, pq, pq_link); @@ -565,6 +568,27 @@ } static __inline void +i_acked_hld(isc_session_t *sp, pdu_t *op) +{ + pduq_t *pq, *tmp; + u_int exp = sp->sn.expCmd; + + pq = NULL; + mtx_lock(&sp->hld_mtx); + TAILQ_FOREACH_SAFE(pq, &sp->hld, pq_link, tmp) { + if((op && op->ipdu.bhs.itt == pq->pdu.ipdu.bhs.itt) + || (pq->ccb == NULL + && (pq->pdu.ipdu.bhs.opcode != ISCSI_WRITE_DATA) + && SNA_GT(exp, ntohl(pq->pdu.ipdu.bhs.ExpStSN)))) { + sp->stats.nhld--; + TAILQ_REMOVE(&sp->hld, pq, pq_link); + pdu_free(sp->isc, pq); + } + } + mtx_unlock(&sp->hld_mtx); +} + +static __inline void i_mbufcopy(struct mbuf *mp, caddr_t dp, int len) { struct mbuf *m; Index: sys/dev/iscsi/initiator/isc_subr.c =================================================================== --- sys/dev/iscsi/initiator/isc_subr.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_subr.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ */ /* | iSCSI - | $Id: isc_subr.c,v 1.20 2006/12/01 09:10:17 danny Exp danny $ + | $Id: isc_subr.c 560 2009-05-07 07:37:49Z danny $ */ #include @@ -58,29 +58,121 @@ #include #include +MALLOC_DEFINE(M_ISC, "iSC", "iSCSI driver options"); + static char * i_strdupin(char *s, size_t maxlen) { size_t len; char *p, *q; - p = malloc(maxlen, M_ISCSI, M_WAITOK); + p = malloc(maxlen, M_ISC, M_WAITOK); if(copyinstr(s, p, maxlen, &len)) { - free(p, M_ISCSI); + free(p, M_ISC); return NULL; } - q = malloc(len, M_ISCSI, M_WAITOK); + q = malloc(len, M_ISC, M_WAITOK); bcopy(p, q, len); - free(p, M_ISCSI); + free(p, M_ISC); return q; } +/*****************************************************************/ +/* */ +/* CRC LOOKUP TABLE */ +/* ================ */ +/* The following CRC lookup table was generated automagically */ +/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ +/* Program V1.0 using the following model parameters: */ +/* */ +/* Width : 4 bytes. */ +/* Poly : 0x1EDC6F41L */ +/* Reverse : TRUE. */ +/* */ +/* For more information on the Rocksoft^tm Model CRC Algorithm, */ +/* see the document titled "A Painless Guide to CRC Error */ +/* Detection Algorithms" by Ross Williams */ +/* (ross@guest.adelaide.edu.au.). This document is likely to be */ +/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/*****************************************************************/ + +static uint32_t crc32Table[256] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L +}; + static uint32_t i_crc32c(const void *buf, size_t size, uint32_t crc) { + const uint8_t *p = buf; + crc = crc ^ 0xffffffff; - crc = calculate_crc32c(crc, buf, size); + while (size--) + crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8); crc = crc ^ 0xffffffff; return crc; } @@ -98,50 +190,51 @@ if(opt->maxXmitDataSegmentLength > 0) { // danny's RFC sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength; - sdebug(2, "maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength); + sdebug(2, "opt.maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength); } if(opt->maxBurstLength != 0) { sp->opt.maxBurstLength = opt->maxBurstLength; - sdebug(2, "maxBurstLength=%d", sp->opt.maxBurstLength); + sdebug(2, "opt.maxBurstLength=%d", sp->opt.maxBurstLength); } if(opt->targetAddress != NULL) { if(sp->opt.targetAddress != NULL) - free(sp->opt.targetAddress, M_ISCSI); + free(sp->opt.targetAddress, M_ISC); sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128); - sdebug(4, "opt.targetAddress='%s'", sp->opt.targetAddress); + sdebug(2, "opt.targetAddress='%s'", sp->opt.targetAddress); } if(opt->targetName != NULL) { if(sp->opt.targetName != NULL) - free(sp->opt.targetName, M_ISCSI); + free(sp->opt.targetName, M_ISC); sp->opt.targetName = i_strdupin(opt->targetName, 128); - sdebug(4, "opt.targetName='%s'", sp->opt.targetName); + sdebug(2, "opt.targetName='%s'", sp->opt.targetName); } if(opt->initiatorName != NULL) { if(sp->opt.initiatorName != NULL) - free(sp->opt.initiatorName, M_ISCSI); + free(sp->opt.initiatorName, M_ISC); sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128); - sdebug(4, "opt.initiatorName='%s'", sp->opt.initiatorName); + sdebug(2, "opt.initiatorName='%s'", sp->opt.initiatorName); } if(opt->maxluns > 0) { if(opt->maxluns > ISCSI_MAX_LUNS) sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ... sp->opt.maxluns = opt->maxluns; - sdebug(4, "opt.maxluns=%d", sp->opt.maxluns); + sdebug(2, "opt.maxluns=%d", sp->opt.maxluns); } if(opt->headerDigest != NULL) { sdebug(2, "opt.headerDigest='%s'", opt->headerDigest); if(strcmp(opt->headerDigest, "CRC32C") == 0) { sp->hdrDigest = (digest_t *)i_crc32c; - sdebug(2, "headerDigest set"); + sdebug(2, "opt.headerDigest set"); } } if(opt->dataDigest != NULL) { + sdebug(2, "opt.dataDigest='%s'", opt->headerDigest); if(strcmp(opt->dataDigest, "CRC32C") == 0) { sp->dataDigest = (digest_t *)i_crc32c; - sdebug(2, "dataDigest set"); + sdebug(2, "opt.dataDigest set"); } } @@ -151,16 +244,18 @@ void i_freeopt(isc_opt_t *opt) { + debug_called(8); + if(opt->targetAddress != NULL) { - free(opt->targetAddress, M_ISCSI); + free(opt->targetAddress, M_ISC); opt->targetAddress = NULL; } if(opt->targetName != NULL) { - free(opt->targetName, M_ISCSI); + free(opt->targetName, M_ISC); opt->targetName = NULL; } if(opt->initiatorName != NULL) { - free(opt->initiatorName, M_ISCSI); + free(opt->initiatorName, M_ISC); opt->initiatorName = NULL; } } Index: sys/dev/iscsi/initiator/iscsi.c =================================================================== --- sys/dev/iscsi/initiator/iscsi.c (revision 210555) +++ sys/dev/iscsi/initiator/iscsi.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,8 +25,7 @@ * */ /* - | iSCSI - | $Id: iscsi.c,v 1.35 2007/04/22 08:58:29 danny Exp danny $ + | $Id: iscsi.c 752 2009-08-20 11:23:28Z danny $ */ #include @@ -56,15 +55,17 @@ #include #include #include +#include #include #include +static char *iscsi_driver_version = "2.2.4.2"; -static char *iscsi_driver_version = "2.1.0"; +static struct isc_softc *isc; -static struct isc_softc isc; - MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI driver"); +MALLOC_DEFINE(M_ISCSIBUF, "iSCbuf", "iSCSI buffers"); +MALLOC_DEFINE(M_TMP, "iSCtmp", "iSCSI tmp"); #ifdef ISCSI_INITIATOR_DEBUG int iscsi_debug = ISCSI_INITIATOR_DEBUG; @@ -74,6 +75,12 @@ struct mtx iscsi_dbg_mtx; #endif +static int max_sessions = MAX_SESSIONS; +SYSCTL_INT(_net, OID_AUTO, iscsi_initiator_max_sessions, CTLFLAG_RDTUN, &max_sessions, MAX_SESSIONS, + "Max sessions allowed"); +static int max_pdus = MAX_PDUS; +SYSCTL_INT(_net, OID_AUTO, iscsi_initiator_max_pdus, CTLFLAG_RDTUN, &max_pdus, MAX_PDUS, + "Max pdu pool"); static char isid[6+1] = { 0x80, @@ -91,6 +98,7 @@ static int i_send(struct cdev *dev, caddr_t arg, struct thread *td); static int i_recv(struct cdev *dev, caddr_t arg, struct thread *td); static int i_setsoc(isc_session_t *sp, int fd, struct thread *td); +static int i_fullfeature(struct cdev *dev, int flag); static d_open_t iscsi_open; static d_close_t iscsi_close; @@ -117,39 +125,28 @@ debug(7, "dev=%d", dev2unit(dev)); - if(dev2unit(dev) > MAX_SESSIONS) { + if(dev2unit(dev) > max_sessions) { // should not happen return ENODEV; } - if(dev2unit(dev) == MAX_SESSIONS) { -#if 1 - struct isc_softc *sc = (struct isc_softc *)dev->si_drv1; - - // this should be in iscsi_start - if(sc->cam_sim == NULL) - ic_init(sc); -#endif - } return 0; } static int iscsi_close(struct cdev *dev, int flag, int otyp, struct thread *td) { - struct isc *sc; isc_session_t *sp; debug_called(8); - debug(3, "flag=%x", flag); + debug(3, "session=%d flag=%x", dev2unit(dev), flag); - sc = (struct isc *)dev->si_drv1; - if(dev2unit(dev) == MAX_SESSIONS) { + if(dev2unit(dev) == max_sessions) { return 0; } - sp = (isc_session_t *)dev->si_drv2; + sp = dev->si_drv2; if(sp != NULL) { - sdebug(2, "session=%d flags=%x", dev2unit(dev), sp->flags ); + sdebug(3, "sp->flags=%x", sp->flags ); /* | if still in full phase, this probably means | that something went realy bad. @@ -170,19 +167,19 @@ static int iscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, struct thread *td) { - struct isc *sc; + struct isc_softc *sc; isc_session_t *sp; isc_opt_t *opt; int error; - sc = (struct isc *)dev->si_drv1; debug_called(8); error = 0; - if(dev2unit(dev) == MAX_SESSIONS) { + if(dev2unit(dev) == max_sessions) { /* | non Session commands */ + sc = dev->si_drv1; if(sc == NULL) return ENXIO; @@ -190,18 +187,17 @@ case ISCSISETSES: error = i_create_session(dev, (int *)arg); if(error == 0) - - break; + break; default: - error = ENXIO; // XXX: + error = ENXIO; } return error; } - sp = (isc_session_t *)dev->si_drv2; /* | session commands */ + sp = dev->si_drv2; if(sp == NULL) return ENXIO; @@ -230,7 +226,7 @@ break; case ISCSISTART: - error = sp->soc == NULL? ENOTCONN: ism_fullfeature(dev, 1); + error = sp->soc == NULL? ENOTCONN: i_fullfeature(dev, 1); if(error == 0) { sp->proc = td->td_proc; SYSCTL_ADD_UINT(&sp->clist, @@ -243,11 +239,11 @@ break; case ISCSIRESTART: - error = sp->soc == NULL? ENOTCONN: ism_fullfeature(dev, 2); + error = sp->soc == NULL? ENOTCONN: i_fullfeature(dev, 2); break; case ISCSISTOP: - error = ism_fullfeature(dev, 0); + error = i_fullfeature(dev, 0); break; case ISCSISIGNAL: { @@ -283,9 +279,9 @@ pduq_t *pq; char buf[1024]; - sc = (struct isc_softc *)dev->si_drv1; - sp = (isc_session_t *)dev->si_drv2; - if(dev2unit(dev) == MAX_SESSIONS) { + sc = dev->si_drv1; + sp = dev->si_drv2; + if(dev2unit(dev) == max_sessions) { sprintf(buf, "/----- Session ------/\n"); uiomove(buf, strlen(buf), uio); int i = 0; @@ -310,10 +306,11 @@ int i = 0; struct socket *so = sp->soc; #define pukeit(i, pq) do {\ - sprintf(buf, "%03d] %06x %02x %x %ld %jd\n",\ - i, ntohl( pq->pdu.ipdu.bhs.CmdSN), \ + sprintf(buf, "%03d] %06x %02x %06x %06x %zd\n",\ + i, ntohl(pq->pdu.ipdu.bhs.CmdSN),\ pq->pdu.ipdu.bhs.opcode, ntohl(pq->pdu.ipdu.bhs.itt),\ - (long)pq->ts.sec, pq->ts.frac);\ + ntohl(pq->pdu.ipdu.bhs.ExpStSN),\ + pq->ts.sec);\ } while(0) sprintf(buf, "%d/%d /---- hld -----/\n", sp->stats.nhld, sp->stats.max_hld); @@ -418,8 +415,7 @@ static int i_send(struct cdev *dev, caddr_t arg, struct thread *td) { - isc_session_t *sp = (isc_session_t *)dev->si_drv2; - struct isc_softc *sc = (struct isc_softc *)dev->si_drv1; + isc_session_t *sp = dev->si_drv2; caddr_t bp; pduq_t *pq; pdu_t *pp; @@ -430,38 +426,46 @@ if(sp->soc == NULL) return ENOTCONN; - if((pq = pdu_alloc(sc, M_NOWAIT)) == NULL) + if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) return EAGAIN; pp = &pq->pdu; pq->pdu = *(pdu_t *)arg; if((error = i_prepPDU(sp, pq)) != 0) goto out; - sdebug(3, "len=%d ahs_len=%d ds_len=%d", pq->len, pp->ahs_len, pp->ds_len); - - pq->buf = bp = malloc(pq->len - sizeof(union ipdu_u), M_ISCSI, M_NOWAIT); - if(pq->buf == NULL) { - error = EAGAIN; - goto out; + bp = NULL; + if((pq->len - sizeof(union ipdu_u)) > 0) { + pq->buf = bp = malloc(pq->len - sizeof(union ipdu_u), M_ISCSIBUF, M_NOWAIT); + if(pq->buf == NULL) { + error = EAGAIN; + goto out; + } } + else + pq->buf = NULL; // just in case? + + sdebug(2, "len=%d ahs_len=%d ds_len=%d buf=%zu@%p", + pq->len, pp->ahs_len, pp->ds_len, pq->len - sizeof(union ipdu_u), bp); + if(pp->ahs_len) { + // XXX: never tested, looks suspicious n = pp->ahs_len; - error = copyin(pp->ahs, bp, n); + error = copyin(pp->ahs_addr, bp, n); if(error != 0) { sdebug(3, "copyin ahs: error=%d", error); goto out; } - pp->ahs = (ahs_t *)bp; + pp->ahs_addr = (ahs_t *)bp; bp += n; } if(pp->ds_len) { n = pp->ds_len; - error = copyin(pp->ds, bp, n); + error = copyin(pp->ds_addr, bp, n); if(error != 0) { sdebug(3, "copyin ds: error=%d", error); goto out; } - pp->ds = bp; + pp->ds_addr = bp; bp += n; while(n & 03) { n++; @@ -470,24 +474,19 @@ } error = isc_qout(sp, pq); -#if 1 if(error == 0) wakeup(&sp->flags); // XXX: to 'push' proc_out ... -#endif out: if(error) - pdu_free(sc, pq); + pdu_free(sp->isc, pq); return error; } -/* - | NOTE: must calculate digest if requiered. - */ static int i_recv(struct cdev *dev, caddr_t arg, struct thread *td) { - isc_session_t *sp = (isc_session_t *)dev->si_drv2; + isc_session_t *sp = dev->si_drv2; pduq_t *pq; pdu_t *pp, *up; caddr_t bp; @@ -501,7 +500,6 @@ if(sp->soc == NULL) return ENOTCONN; - sdebug(3, ""); cnt = 6; // XXX: maybe the user can request a time out? mtx_lock(&sp->rsp_mtx); while((pq = TAILQ_FIRST(&sp->rsp)) == NULL) { @@ -514,7 +512,7 @@ } mtx_unlock(&sp->rsp_mtx); - sdebug(4, "cnt=%d", cnt); + sdebug(6, "cnt=%d", cnt); if(pq == NULL) { error = ENOTCONN; @@ -536,19 +534,15 @@ len = 0; if(pp->ahs_len) { len += pp->ahs_len; - if(sp->hdrDigest) - len += 4; } if(pp->ds_len) { len += pp->ds_len; - if(sp->hdrDigest) - len += 4; } mustfree = 0; if(len > pq->mp->m_len) { mustfree++; - bp = malloc(len, M_ISCSI, M_WAITOK); + bp = malloc(len, M_TMP, M_WAITOK); sdebug(4, "need mbufcopy: %d", len); i_mbufcopy(pq->mp, bp, len); } @@ -557,28 +551,24 @@ if(pp->ahs_len) { need = pp->ahs_len; - if(sp->hdrDigest) - need += 4; n = MIN(up->ahs_size, need); - error = copyout(bp, (caddr_t)up->ahs, n); + error = copyout(bp, (caddr_t)up->ahs_addr, n); up->ahs_len = n; bp += need; } if(!error && pp->ds_len) { need = pp->ds_len; - if(sp->hdrDigest) - need += 4; if((have = up->ds_size) == 0) { have = up->ahs_size - n; - up->ds = (caddr_t)up->ahs + n; + up->ds_addr = (caddr_t)up->ahs_addr + n; } n = MIN(have, need); - error = copyout(bp, (caddr_t)up->ds, n); + error = copyout(bp, (caddr_t)up->ds_addr, n); up->ds_len = n; } if(mustfree) - free(bp, M_ISCSI); + free(bp, M_TMP); } sdebug(6, "len=%d ahs_len=%d ds_len=%d", pq->len, pp->ahs_len, pp->ds_len); @@ -589,33 +579,57 @@ } static int +i_fullfeature(struct cdev *dev, int flag) +{ + isc_session_t *sp = dev->si_drv2; + int error; + + sdebug(2, "flag=%d", flag); + + error = 0; + switch(flag) { + case 0: // stop + sp->flags &= ~ISC_FFPHASE; + break; + case 1: // start + sp->flags |= ISC_FFPHASE; + error = ic_init(sp); + break; + case 2: // restart + sp->flags |= ISC_FFPHASE; + ism_restart(sp); + break; + } + return error; +} + +static int i_create_session(struct cdev *dev, int *ndev) { - struct isc_softc *sc = (struct isc_softc *)dev->si_drv1; + struct isc_softc *sc = dev->si_drv1; isc_session_t *sp; int error, n; debug_called(8); - sp = (isc_session_t *)malloc(sizeof *sp, M_ISCSI, M_WAITOK | M_ZERO); + + sp = malloc(sizeof(isc_session_t), M_ISCSI, M_WAITOK | M_ZERO); if(sp == NULL) return ENOMEM; - mtx_lock(&sc->mtx); - /* - | search for the lowest unused sid - */ - for(n = 0; n < MAX_SESSIONS; n++) - if(sc->sessions[n] == NULL) - break; - if(n == MAX_SESSIONS) { - mtx_unlock(&sc->mtx); + + sx_xlock(&sc->unit_sx); + if((n = alloc_unr(sc->unit)) < 0) { + sx_unlock(&sc->unit_sx); free(sp, M_ISCSI); + xdebug("too many sessions!"); return EPERM; } + sx_unlock(&sc->unit_sx); + + mtx_lock(&sc->isc_mtx); TAILQ_INSERT_TAIL(&sc->isc_sess, sp, sp_link); - sc->nsess++; - mtx_unlock(&sc->mtx); + isc->nsess++; + mtx_unlock(&sc->isc_mtx); - sc->sessions[n] = sp; sp->dev = make_dev(&iscsi_cdevsw, n, UID_ROOT, GID_WHEEL, 0600, "iscsi%d", n); *ndev = sp->sid = n; sp->isc = sc; @@ -624,10 +638,9 @@ sp->opt.maxRecvDataSegmentLength = 8192; sp->opt.maxXmitDataSegmentLength = 8192; - sp->opt.maxBurstLength = 65536; // 64k + sp->opt.maxluns = ISCSI_MAX_LUNS; - sdebug(2, "sessionID=%d sp=%p", n, sp); error = ism_start(sp); return error; @@ -663,7 +676,7 @@ static void iscsi_shutdown(void *v) { - struct isc_softc *sc = (struct isc_softc *)v; + struct isc_softc *sc = v; isc_session_t *sp; int n; @@ -672,12 +685,14 @@ xdebug("sc is NULL!"); return; } +#ifdef DO_EVENTHANDLER if(sc->eh == NULL) debug(2, "sc->eh is NULL"); else { EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->eh); debug(2, "done n=%d", sc->nsess); } +#endif n = 0; TAILQ_FOREACH(sp, &sc->isc_sess, sp_link) { debug(2, "%2d] sp->flags=0x%08x", n, sp->flags); @@ -686,24 +701,6 @@ debug(2, "done"); } -static int -init_pdus(struct isc_softc *sc) -{ - debug_called(8); - - sc->pdu_zone = uma_zcreate("pdu", sizeof(pduq_t), - NULL, NULL, NULL, NULL, - 0, 0); - if(sc->pdu_zone == NULL) { - printf("iscsi_initiator: uma_zcreate failed"); - return -1; - } - uma_zone_set_max(sc->pdu_zone, MAX_PDUS); - TAILQ_INIT(&sc->freepdu); - - return 0; -} - static void free_pdus(struct isc_softc *sc) { @@ -724,50 +721,52 @@ static void iscsi_start(void) { - struct isc_softc *sc = &isc; - debug_called(8); - memset(sc, 0, sizeof(struct isc_softc)); + TUNABLE_INT_FETCH("net.iscsi_initiator.max_sessions", &max_sessions); + TUNABLE_INT_FETCH("net.iscsi_initiator.max_pdus", &max_pdus); - sc->dev = make_dev(&iscsi_cdevsw, MAX_SESSIONS, UID_ROOT, GID_WHEEL, 0600, "iscsi"); - sc->dev->si_drv1 = sc; + isc = malloc(sizeof(struct isc_softc), M_ISCSI, M_ZERO|M_WAITOK); + isc->dev = make_dev(&iscsi_cdevsw, max_sessions, UID_ROOT, GID_WHEEL, 0600, "iscsi"); + isc->dev->si_drv1 = isc; + mtx_init(&isc->isc_mtx, "iscsi", NULL, MTX_DEF); + mtx_init(&isc->pdu_mtx, "iscsi pdu pool", NULL, MTX_DEF); - TAILQ_INIT(&sc->isc_sess); - if(init_pdus(sc) != 0) - xdebug("pdu zone init failed!"); // XXX: should cause terminal failure ... - - mtx_init(&sc->mtx, "iscsi", NULL, MTX_DEF); - mtx_init(&sc->pdu_mtx, "iscsi pdu pool", NULL, MTX_DEF); + TAILQ_INIT(&isc->isc_sess); + /* + | now init the free pdu list + */ + isc->pdu_zone = uma_zcreate("pdu", sizeof(pduq_t), + NULL, NULL, NULL, NULL, + 0, 0); + if(isc->pdu_zone == NULL) { + xdebug("iscsi_initiator: uma_zcreate failed"); + // XXX: should fail... + } + uma_zone_set_max(isc->pdu_zone, max_pdus); + TAILQ_INIT(&isc->freepdu); + isc->unit = new_unrhdr(0, max_sessions-1, NULL); + sx_init(&isc->unit_sx, "iscsi sx"); -#if 0 - // XXX: this will cause a panic if the - // module is loaded too early - if(ic_init(sc) != 0) - return; -#else - sc->cam_sim = NULL; -#endif - #ifdef DO_EVENTHANDLER - if((sc->eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, iscsi_shutdown, + if((isc->eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, iscsi_shutdown, sc, SHUTDOWN_PRI_DEFAULT-1)) == NULL) xdebug("shutdown event registration failed\n"); #endif /* | sysctl stuff */ - sysctl_ctx_init(&sc->clist); - sc->oid = SYSCTL_ADD_NODE(&sc->clist, + sysctl_ctx_init(&isc->clist); + isc->oid = SYSCTL_ADD_NODE(&isc->clist, SYSCTL_STATIC_CHILDREN(_net), OID_AUTO, - "iscsi", + "iscsi_initiator", CTLFLAG_RD, 0, "iSCSI Subsystem"); - SYSCTL_ADD_STRING(&sc->clist, - SYSCTL_CHILDREN(sc->oid), + SYSCTL_ADD_STRING(&isc->clist, + SYSCTL_CHILDREN(isc->oid), OID_AUTO, "driver_version", CTLFLAG_RD, @@ -775,8 +774,8 @@ 0, "iscsi driver version"); - SYSCTL_ADD_STRING(&sc->clist, - SYSCTL_CHILDREN(sc->oid), + SYSCTL_ADD_STRING(&isc->clist, + SYSCTL_CHILDREN(isc->oid), OID_AUTO, "isid", CTLFLAG_RW, @@ -784,13 +783,13 @@ 6+1, "initiator part of the Session Identifier"); - SYSCTL_ADD_INT(&sc->clist, - SYSCTL_CHILDREN(sc->oid), + SYSCTL_ADD_INT(&isc->clist, + SYSCTL_CHILDREN(isc->oid), OID_AUTO, "sessions", CTLFLAG_RD, - &sc->nsess, - sizeof(sc->nsess), + &isc->nsess, + sizeof(isc->nsess), "number of active session"); printf("iscsi: version %s\n", iscsi_driver_version); @@ -804,7 +803,6 @@ static void iscsi_stop(void) { - struct isc_softc *sc = &isc; isc_session_t *sp, *sp_tmp; debug_called(8); @@ -813,24 +811,26 @@ | go through all the sessions | Note: close should have done this ... */ - TAILQ_FOREACH_SAFE(sp, &sc->isc_sess, sp_link, sp_tmp) { + TAILQ_FOREACH_SAFE(sp, &isc->isc_sess, sp_link, sp_tmp) { //XXX: check for activity ... ism_stop(sp); + if(sp->cam_sim != NULL) + ic_destroy(sp); } - if(sc->cam_sim != NULL) - ic_destroy(sc); + mtx_destroy(&isc->isc_mtx); + mtx_destroy(&isc->pdu_mtx); + sx_destroy(&isc->unit_sx); - mtx_destroy(&sc->mtx); - mtx_destroy(&sc->pdu_mtx); - free_pdus(sc); + free_pdus(isc); - if(sc->dev) - destroy_dev(sc->dev); + if(isc->dev) + destroy_dev(isc->dev); - if(sysctl_ctx_free(&sc->clist)) + if(sysctl_ctx_free(&isc->clist)) xdebug("sysctl_ctx_free failed"); - iscsi_shutdown(sc); // XXX: check EVENTHANDLER_ ... + iscsi_shutdown(isc); // XXX: check EVENTHANDLER_ ... + free(isc, M_ISCSI); } static int @@ -844,13 +844,12 @@ break; case MOD_QUIESCE: -#if 1 - if(isc.nsess) { - xdebug("iscsi module busy(nsess=%d), cannot unload", isc.nsess); + if(isc->nsess) { + xdebug("iscsi module busy(nsess=%d), cannot unload", isc->nsess); log(LOG_ERR, "iscsi module busy, cannot unload"); } - return isc.nsess; -#endif + return isc->nsess; + case MOD_SHUTDOWN: break; Index: sys/dev/iscsi/initiator/isc_sm.c =================================================================== --- sys/dev/iscsi/initiator/isc_sm.c (revision 210555) +++ sys/dev/iscsi/initiator/isc_sm.c (working copy) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Daniel Braniss + * Copyright (c) 2005-2010 Daniel Braniss * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ */ /* | iSCSI - Session Manager - | $Id: isc_sm.c,v 1.30 2007/04/22 09:53:09 danny Exp danny $ + | $Id: isc_sm.c 743 2009-08-08 10:54:53Z danny $ */ #include @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -131,8 +132,10 @@ debug_called(8); opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 0); debug(5, "itt=%x pq=%p opq=%p", ntohl(pq->pdu.ipdu.bhs.itt), pq, opq); - if(opq != NULL) + if(opq != NULL) { iscsi_done(sp, opq, pq); + i_acked_hld(sp, &pq->pdu); + } else xdebug("%d] we lost something itt=%x", sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); @@ -267,7 +270,7 @@ len += pp->ahs_len; bhp->AHSLength = pp->ahs_len / 4; } - if(sp->hdrDigest) + if(ISOK2DIG(sp->hdrDigest, pp)) len += 4; if(pp->ds_len) { n = pp->ds_len; @@ -283,7 +286,7 @@ n = 4 - (len & 03); len += n; } - if(sp->dataDigest) + if(ISOK2DIG(sp->dataDigest, pp)) len += 4; } @@ -321,7 +324,7 @@ mtx_lock(&sp->io_mtx); sp->flags |= ISC_OQNOTEMPTY; if(sp->flags & ISC_OWAITING) - wakeup(&sp->flags); + wakeup(&sp->flags); mtx_unlock(&sp->io_mtx); return error; @@ -329,7 +332,7 @@ /* | called when a fullPhase is restarted */ -static void +void ism_restart(isc_session_t *sp) { int lastcmd; @@ -348,32 +351,9 @@ } mtx_unlock(&sp->io_mtx); - sdebug(2, "restarted lastcmd=0x%x", lastcmd); + sdebug(2, "restarted sn.cmd=0x%x lastcmd=0x%x", sp->sn.cmd, lastcmd); } -int -ism_fullfeature(struct cdev *dev, int flag) -{ - isc_session_t *sp = (isc_session_t *)dev->si_drv2; - int error; - - sdebug(2, "flag=%d", flag); - - error = 0; - switch(flag) { - case 0: // stop - sp->flags &= ~ISC_FFPHASE; - break; - case 1: // start - error = ic_fullfeature(dev); - break; - case 2: // restart - ism_restart(sp); - break; - } - return error; -} - void ism_recv(isc_session_t *sp, pduq_t *pq) { @@ -384,26 +364,6 @@ bhs = &pq->pdu.ipdu.bhs; statSN = ntohl(bhs->OpcodeSpecificFields[1]); -#if 0 - { - /* - | this code is only for debugging. - */ - sn_t *sn = &sp->sn; - if(sp->cws == 0) { - if((sp->flags & ISC_STALLED) == 0) { - sdebug(4, "window closed: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", - sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); - sp->flags |= ISC_STALLED; - } else - if(sp->flags & ISC_STALLED) { - sdebug(4, "window opened: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", - sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); - sp->flags &= ~ISC_STALLED; - } - } - } -#endif #ifdef notyet if(sp->sn.expCmd != sn->cmd) { @@ -454,7 +414,7 @@ break; } } - + /* | go through the out queues looking for work | if either nothing to do, or window is closed @@ -465,11 +425,10 @@ { sn_t *sn = &sp->sn; pduq_t *pq; - int error, ndone; - int which; + int error, which; debug_called(8); - error = ndone = 0; + error = 0; while(sp->flags & ISC_LINK_UP) { pdu_t *pp; @@ -508,7 +467,7 @@ sn->cmd++; case ISCSI_WRITE_DATA: - bhs->ExpStSN = htonl(sn->stat); + bhs->ExpStSN = htonl(sn->stat + 1); break; default: @@ -523,19 +482,21 @@ bhs->opcode, sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt); - if(pq->ccb) + if(bhs->opcode != ISCSI_NOP_OUT) + /* + | enqued till ack is received + | note: sosend(...) does not mean the packet left + | the host so that freeing resources has to wait + */ i_nqueue_hld(sp, pq); - if((error = isc_sendPDU(sp, pq)) == 0) { - ndone++; - if(pq->ccb == NULL) - pdu_free(sp->isc, pq); - } - else { - xdebug("error=%d ndone=%d opcode=0x%x ccb=%p itt=%x", - error, ndone, bhs->opcode, pq->ccb, ntohl(bhs->itt)); - if(pq->ccb) - i_remove_hld(sp, pq); + error = isc_sendPDU(sp, pq); + if(bhs->opcode == ISCSI_NOP_OUT) + pdu_free(sp->isc, pq); + if(error) { + xdebug("error=%d opcode=0x%x ccb=%p itt=%x", + error, bhs->opcode, pq->ccb, ntohl(bhs->itt)); + i_remove_hld(sp, pq); switch(error) { case EPIPE: sp->flags &= ~ISC_LINK_UP; @@ -546,12 +507,12 @@ break; default: - if(pq->ccb) { + if(pq->ccb) { xdebug("back to cam"); pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error? - XPT_DONE(sp->isc, pq->ccb); + XPT_DONE(sp, pq->ccb); pdu_free(sp->isc, pq); - } + } else xdebug("we lost it!"); } @@ -559,12 +520,12 @@ } return error; } - + /* | survives link breakdowns. */ static void -ism_proc(void *vp) +ism_out(void *vp) { isc_session_t *sp = (isc_session_t *)vp; int error; @@ -580,8 +541,11 @@ sdebug(3, "error=%d", error); } } - mtx_lock(&sp->io_mtx); + mtx_lock(&sp->io_mtx); if((sp->flags & ISC_LINK_UP) == 0) { + sdebug(3, "ISC_LINK_UP==0, sp->flags=%x ", sp->flags); + if(sp->soc != NULL) + sdebug(3, "so_state=%x", sp->soc->so_state); wakeup(&sp->soc); } @@ -589,7 +553,7 @@ sp->flags |= ISC_OWAITING; if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) { if(sp->flags & ISC_CON_RUNNING) - _nop_out(sp); + _nop_out(sp); } sp->flags &= ~ISC_OWAITING; } @@ -600,14 +564,20 @@ sp->flags &= ~ISC_SM_RUNNING; sdebug(3, "dropped ISC_SM_RUNNING"); + wakeup(&sp->soc); + wakeup(sp); // XXX: do we need this one? + #if __FreeBSD_version >= 700000 destroy_dev(sp->dev); #endif - wakeup(sp); debug(3, "terminated sp=%p sp->sid=%d", sp, sp->sid); +#if __FreeBSD_version >= 800000 kproc_exit(0); +#else + kthread_exit(0); +#endif } #if 0 @@ -753,12 +723,16 @@ (void)i_pdu_flush(sp); - ic_lost_target(sp, sp->sid); + ic_destroy(sp); - mtx_lock(&sc->mtx); + sx_xlock(&sc->unit_sx); + free_unr(sc->unit, sp->sid); + sx_xunlock(&sc->unit_sx); + + mtx_lock(&sc->isc_mtx); TAILQ_REMOVE(&sc->isc_sess, sp, sp_link); sc->nsess--; - mtx_unlock(&sc->mtx); + mtx_unlock(&sc->isc_mtx); #if __FreeBSD_version < 700000 destroy_dev(sp->dev); @@ -771,7 +745,6 @@ mtx_destroy(&sp->io_mtx); i_freeopt(&sp->opt); - sc->sessions[sp->sid] = NULL; if(sysctl_ctx_free(&sp->clist)) xdebug("sysctl_ctx_free failed"); @@ -792,17 +765,11 @@ TAILQ_INIT(&sp->isnd); TAILQ_INIT(&sp->wsnd); TAILQ_INIT(&sp->hld); -#if 1 + mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_DEF); mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_DEF); mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_DEF); mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_DEF); -#else - mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_SPIN); - mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_SPIN); - mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_SPIN); - mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_SPIN); -#endif mtx_init(&sp->io_mtx, "iscsi-io", NULL, MTX_DEF); isc_add_sysctls(sp); @@ -810,5 +777,10 @@ sp->flags |= ISC_SM_RUN; debug(4, "starting ism_proc: sp->sid=%d", sp->sid); - return kproc_create(ism_proc, sp, &sp->stp, 0, 0, "ism_%d", sp->sid); + +#if __FreeBSD_version >= 800000 + return kproc_create(ism_out, sp, &sp->stp, 0, 0, "isc_out %d", sp->sid); +#else + return kthread_create(ism_out, sp, &sp->stp, 0, 0, "isc_out %d", sp->sid); +#endif } --=-=-=-- From owner-freebsd-scsi@FreeBSD.ORG Wed Jul 28 10:50:05 2010 Return-Path: Delivered-To: freebsd-scsi@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 13544106566B for ; Wed, 28 Jul 2010 10:50:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 023ED8FC16 for ; Wed, 28 Jul 2010 10:50:05 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o6SAo4Zt055706 for ; Wed, 28 Jul 2010 10:50:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o6SAo4aa055705; Wed, 28 Jul 2010 10:50:04 GMT (envelope-from gnats) Date: Wed, 28 Jul 2010 10:50:04 GMT Message-Id: <201007281050.o6SAo4aa055705@freefall.freebsd.org> To: freebsd-scsi@FreeBSD.org From: Volodymyr Kostyrko Cc: Subject: Re: kern/147704: [mpt] sys/dev/mpt: new chip revision, partially unsupported X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Volodymyr Kostyrko List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2010 10:50:05 -0000 The following reply was made to PR kern/147704; it has been noted by GNATS. From: Volodymyr Kostyrko To: bug-followup@FreeBSD.org Cc: Subject: Re: kern/147704: [mpt] sys/dev/mpt: new chip revision, partially unsupported Date: Wed, 28 Jul 2010 13:40:31 +0300 Sorry, I was wrong. It's not about mpt driver, it's about firmware. This RAID controller may be flashed with three distinct firmwares: 1. IR. Integrated RAID. Needs I-Button chip to work. 2. SR. Software RAID. Unsupported on FreeBSD. 3. IT. Integrated Target. Shows connected device only. I've contacted SuperMicro and obtained firmware to flash my controller from SR mode to IT mode and now it works. Maybe it's just worth mentioning on mpt(4) about different firmwares available? -- Sphinx of black quartz judge my vow. From owner-freebsd-scsi@FreeBSD.ORG Thu Jul 29 13:19:56 2010 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 907C81065670 for ; Thu, 29 Jul 2010 13:19:56 +0000 (UTC) (envelope-from samflanker@gmail.com) Received: from mail-ew0-f54.google.com (mail-ew0-f54.google.com [209.85.215.54]) by mx1.freebsd.org (Postfix) with ESMTP id 234F98FC14 for ; Thu, 29 Jul 2010 13:19:55 +0000 (UTC) Received: by ewy26 with SMTP id 26so113072ewy.13 for ; Thu, 29 Jul 2010 06:19:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:content-type :content-transfer-encoding; bh=1E5VClI9qMjj6zj4c5QtDaOrDBd+Zay/Cl6fSd1HnPE=; b=O+vo3mQIuGaKth+oqMc4q+CtoRpoAExAjp2vMTfcU4T1KpgltGaZUkUzzo6wRtVxrB z7FVQhFpt7tp02yJJmMdIDpc19iFrVyN9oujayFmkV2kohgbpLAjBUc8aAE88ElT5wpr DsO6lweZZVjQWwHJsFb1UHOI4+uRxhre0Mk5k= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; b=uQap9CghleiBOjs461EdSAJaLKliYwqHOaHk4yNPfP0QX3/P9+nYPvlhVjvc2lUrCH l8zqauv/TjisXLDKe7viHt2mS9mB5mHZAwKvGawnOl5yvqH74P6mQJ0uHwo8pGv05oyB yeADJGOnwlyWL3Rq1A6ytKIHwWEEZp5getChw= Received: by 10.14.53.71 with SMTP id f47mr28913eec.14.1280407728318; Thu, 29 Jul 2010 05:48:48 -0700 (PDT) Received: from localhost.localdomain ([213.152.137.43]) by mx.google.com with ESMTPS id a48sm1211932eei.7.2010.07.29.05.48.47 (version=SSLv3 cipher=RC4-MD5); Thu, 29 Jul 2010 05:48:47 -0700 (PDT) Message-ID: <4C5178CE.2080301@gmail.com> Date: Thu, 29 Jul 2010 16:49:18 +0400 From: venom User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100430 Fedora/3.0.4-2.fc12 Thunderbird/3.0.4 MIME-Version: 1.0 To: freebsd-scsi@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: mpt, interrupt storm detected, different IRQ X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Jul 2010 13:19:56 -0000 Hello problem interrupt storm detected FreeBSD 8.1-RELEASE amd64 -- from /var/log/messages interrupt storm detected on "irq16:"; throttling interrupt source |# vmstat -i | awk "/rate|mpt|uhci/" interrupt total rate irq16: uhci3 uhci4* 430408 786 irq19: uhci0 uhci1* 26 0 irq24: mpt0 375534 686| # mptutil show adapter mpt0 Adapter: Board Name: SAS3801E Board Assembly: L3-01123-04E Chip Name: C1068E Chip Revision: UNUSED RAID Levels: none interrupt storm detected on mpt activity, usb devices is not connected problem in mpt driver ? /Vladimir Ermakov