From owner-freebsd-scsi@FreeBSD.ORG Wed Apr 25 05:44:56 2007 Return-Path: X-Original-To: freebsd-scsi@freebsd.org Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2EAC416A406 for ; Wed, 25 Apr 2007 05:44:56 +0000 (UTC) (envelope-from josh.carroll@gmail.com) Received: from wx-out-0506.google.com (wx-out-0506.google.com [66.249.82.232]) by mx1.freebsd.org (Postfix) with ESMTP id D5A5213C45A for ; Wed, 25 Apr 2007 05:44:55 +0000 (UTC) (envelope-from josh.carroll@gmail.com) Received: by wx-out-0506.google.com with SMTP id s18so116716wxc for ; Tue, 24 Apr 2007 22:44:55 -0700 (PDT) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=UHk2jL5wKcrYno30pCXLNnk8a5GybsgQ8tboXz9cE9Nwz4VYZocVAFLEzcVsGChnGZYq7mwSFl0fDc47bI9k8jbMETajsYFr8eGrLD7Ealg7BzMkHswu0xUowANcPbmDevIv/B4uJ9UnZn9jAgcmUeYXiPTUmoeM+QnZZ3rHyHI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=FIvwY7vQ3S5wVN4tjMJZ0qFaZ8PG6B2CTwS2NqO21ZNDu3bU72MCWqJ7gKacm+az7c3qA3EL5zADTd2GxjQYH7xW+etaNjicsTeJiLfQlcM4DdI/3KVHs6AFVc6YBd/9N+xT19P2Fo0cbqlNIiGHnRYxW60IRBbYUK3rXxdg4Xo= Received: by 10.70.129.4 with SMTP id b4mr280109wxd.1177479894822; Tue, 24 Apr 2007 22:44:54 -0700 (PDT) Received: by 10.100.231.9 with HTTP; Tue, 24 Apr 2007 22:44:54 -0700 (PDT) Message-ID: <8cb6106e0704242244i6b23e0a3s9a7c47cefd7975d7@mail.gmail.com> Date: Tue, 24 Apr 2007 22:44:54 -0700 From: "Josh Carroll" To: "Thomas Quinot" In-Reply-To: <8cb6106e0704242119h4a09d7d4v667d64071b3bd053@mail.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <8cb6106e0703261318o120c620ar6b2461802632fc01@mail.gmail.com> <8cb6106e0703281531k4c5bebecp5566c64c8f458a74@mail.gmail.com> <8cb6106e0704030039if46397fvfc993d9c9e19e1fc@mail.gmail.com> <8cb6106e0704032107w457026b1t1e04ed11008af48a@mail.gmail.com> <20070424162008.GA7087@melamine.cuivre.fr.eu.org> <8cb6106e0704240929j38178df6k1b6391446c69a2ae@mail.gmail.com> <20070424165843.GD7087@melamine.cuivre.fr.eu.org> <8cb6106e0704241132vfa6b312s3b4cbea0c823b796@mail.gmail.com> <8cb6106e0704241845r737dca05p50fc967a61d66677@mail.gmail.com> <8cb6106e0704242119h4a09d7d4v667d64071b3bd053@mail.gmail.com> Cc: freebsd-scsi@freebsd.org, bug-followup@freebsd.org, c47g@gmx.at Subject: Re: kern/103602: drive gets wedged on READ CD CAPACITY if no disc is in X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: josh.carroll@gmail.com List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Apr 2007 05:44:56 -0000 Oops, I think gmail attached the patch as a MIME encoded attachment. Here's the patch: diff -urN sys.old/cam/cam_xpt.c sys/cam/cam_xpt.c --- sys.old/cam/cam_xpt.c Sat Sep 23 11:42:08 2006 +++ sys/cam/cam_xpt.c Tue Apr 24 13:31:28 2007 @@ -254,6 +254,11 @@ static struct xpt_quirk_entry xpt_quirk_table[] = { { + /* Hangs on INQUIRY with EVPD flag??? */ + { T_CDROM, SIP_MEDIA_REMOVABLE, sony, "DVD RW DRU*", "*" }, + CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/0 + }, + { /* Reports QUEUE FULL for temporary resource shortages */ { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP39100*", "*" }, /*quirks*/0, /*mintags*/24, /*maxtags*/32 diff -urN sys.old/cam/scsi/scsi_cd.c sys/cam/scsi/scsi_cd.c --- sys.old/cam/scsi/scsi_cd.c Wed Jul 26 00:48:51 2006 +++ sys/cam/scsi/scsi_cd.c Tue Apr 24 13:31:28 2007 @@ -107,9 +107,10 @@ } cd_flags; typedef enum { - CD_CCB_PROBE = 0x01, - CD_CCB_BUFFER_IO = 0x02, - CD_CCB_WAITING = 0x03, + CD_CCB_PROBE_TUR = 0x01, + CD_CCB_PROBE_RCAP = 0x02, + CD_CCB_BUFFER_IO = 0x03, + CD_CCB_WAITING = 0x04, CD_CCB_TYPE_MASK = 0x0F, CD_CCB_RETRY_UA = 0x10 } cd_ccb_state; @@ -135,7 +136,8 @@ }; typedef enum { - CD_STATE_PROBE, + CD_STATE_PROBE_RCAP, + CD_STATE_PROBE_TUR, CD_STATE_NORMAL } cd_state; @@ -675,7 +677,7 @@ bzero(softc, sizeof(*softc)); LIST_INIT(&softc->pending_ccbs); STAILQ_INIT(&softc->mode_queue); - softc->state = CD_STATE_PROBE; + softc->state = CD_STATE_PROBE_TUR; bioq_init(&softc->bio_queue); if (SID_IS_REMOVABLE(&cgd->inq_data)) softc->flags |= CD_FLAG_DISC_REMOVABLE; @@ -1561,7 +1563,21 @@ } break; } - case CD_STATE_PROBE: + case CD_STATE_PROBE_TUR: + { + csio = &start_ccb->csio; + scsi_test_unit_ready(csio, + /*retries*/4, + cddone, + MSG_SIMPLE_Q_TAG, + SSD_FULL_SIZE, + /*timeout*/10000); + start_ccb->ccb_h.ccb_bp = NULL; + start_ccb->ccb_h.ccb_state = CD_CCB_PROBE_TUR; + xpt_action(start_ccb); + break; + } + case CD_STATE_PROBE_RCAP: { rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcap), @@ -1582,7 +1598,7 @@ SSD_FULL_SIZE, /*timeout*/20000); start_ccb->ccb_h.ccb_bp = NULL; - start_ccb->ccb_h.ccb_state = CD_CCB_PROBE; + start_ccb->ccb_h.ccb_state = CD_CCB_PROBE_RCAP; xpt_action(start_ccb); break; } @@ -1673,7 +1689,35 @@ biofinish(bp, NULL, 0); break; } - case CD_CCB_PROBE: + case CD_CCB_PROBE_TUR: + { + if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { + softc->state = CD_STATE_PROBE_RCAP; + xpt_release_ccb(done_ccb); + xpt_schedule(periph, /*priority*/5); + return; + } + if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { + /* Don't wedge the queue */ + cam_release_devq(done_ccb->ccb_h.path, + /*relsim_flags*/0, + /*reduction*/0, + /*timeout*/0, + /*getcount_only*/0); + } + if (bootverbose) + cam_error_print(done_ccb, CAM_ESF_ALL, CAM_EPF_ALL); + /* + * The TUR generated an error, so there likely isn't media in + * the drive. Some drives lock up if they are sent a read + * capacity command while in this state, so avoid doing that. + */ + softc->state = CD_STATE_NORMAL; + xpt_release_ccb(done_ccb); + cam_periph_unlock(periph); + return; + } + case CD_CCB_PROBE_RCAP: { struct scsi_read_capacity_data *rdcap; char announce_buf[120]; /* diff -urN sys.old/dev/ata/atapi-cam.c sys/dev/ata/atapi-cam.c --- sys.old/dev/ata/atapi-cam.c Tue Apr 4 09:07:42 2006 +++ sys/dev/ata/atapi-cam.c Tue Apr 24 13:31:22 2007 @@ -505,10 +505,10 @@ switch (ccb_h->flags & CAM_DIR_MASK) { case CAM_DIR_IN: - request_flags |= ATA_R_READ|ATA_R_DMA; + request_flags |= ATA_R_READ; break; case CAM_DIR_OUT: - request_flags |= ATA_R_WRITE|ATA_R_DMA; + request_flags |= ATA_R_WRITE; break; case CAM_DIR_NONE: /* No flags need to be set */ @@ -517,8 +517,6 @@ device_printf(softc->dev, "unknown IO operation\n"); goto action_invalid; } - if (softc->atadev[tid]->mode < ATA_DMA) - request_flags &= ~ATA_R_DMA; if ((hcb = allocate_hcb(softc, unit, bus, ccb)) == NULL) { printf("cannot allocate ATAPI/CAM hcb\n"); @@ -580,7 +578,23 @@ request->u.atapi.ccb[3] = request->u.atapi.ccb[1] & 0x1f; request->u.atapi.ccb[2] = 0; request->u.atapi.ccb[1] = 0; + + case READ_10: + /* FALLTHROUGH */ + case WRITE_10: + /* FALLTHROUGH */ + case READ_12: + /* FALLTHROUGH */ + case WRITE_12: + /* + * Enable DMA (if target supports it) for READ and WRITE commands + * only, as some combinations of drive, controller and chipset do + * not behave correctly when DMA is enabled for other commands. + */ + if (softc->atadev[tid]->mode >= ATA_DMA) + request_flags |= ATA_R_DMA; break; + } if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) { @@ -746,7 +760,9 @@ free_hcb(hcb); ccb->ccb_h.status = status | (ccb->ccb_h.status & ~(CAM_STATUS_MASK | CAM_SIM_QUEUED)); + mtx_lock(&Giant); xpt_done(ccb); + mtx_unlock(&Giant); } static void