freebsd-skq/sys/cam/scsi/scsi_da.c

2085 lines
52 KiB
C
Raw Normal View History

/*-
* Implementation of SCSI Direct Access Peripheral driver for CAM.
*
* Copyright (c) 1997 Justin T. Gibbs.
* 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,
* without modification, immediately at the beginning of the file.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
2003-06-10 18:14:05 +00:00
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bio.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#endif /* _KERNEL */
#include <sys/devicestat.h>
#include <sys/conf.h>
#include <sys/eventhandler.h>
#include <sys/malloc.h>
#include <sys/cons.h>
Some fixes for the CD and DA drivers from bde. (and some of my own as well) Among them: [ cd driver ] 1. Old labeling code was still there. 2. Error handling for dsopen() was broken (no test for the `error' returned by dsopen(); bogus test of an `error' that is known to be 0). 3. cdopen() closed the physical device after certain errors although there may still be open partitions on it. 4. cdclose() closed the physical device although there may still be open partitions on it. 5. Some printf format fixes was incomplete or missing. 6. cdioctl() truncated unit numbers mod 256. 7. cdioctl() was missing locking. [ da driver ] 1. daclose() closed the physical device although there may still be open partitions on it. This was fixed many years ago in sd.c rev.1.57. 2. A minor optimization (the dk_slices != NULL test) in sdopen() became uglier in daopen(). It is not worth doing. da only regressed compared with od and my version of sd, since I never committed the change to sd. daopen() should probably do less if some partition is already open. This is not addressed by the diffs. [ ... ] 5. "opt_hw_wdog.h" was not included, so the HW_WDOG code was unreachable. - Added a getdev CCB call in the cdopen() and daopen() calls so that the vendor name and device name are available for the disklabel. (suggested by bde) - Removed vestigal devfs support in both drivers, since we can't properly work with devfs yet. (ask bde for details on this) - Cleaned up the probe code in both drivers in the failure cases. There were a number of things wrong here. The peripheral driver instances weren't getting properly cleaned up. Sometimes the wrong probe message would get printed out (with the failure message appended), so it wasn't very clear that we failed to attach. SCSI sense information was printed, even when the error in question wasn't a SCSI error. I put similar fixes into the changer driver in revision 1.2 of scsi_ch.c. Reviewed by: gibbs Submitted by: bde (partially)
1998-10-07 02:57:57 +00:00
#include <machine/md_var.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <geom/geom_disk.h>
#ifndef _KERNEL
#include <stdio.h>
#include <string.h>
#endif /* _KERNEL */
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_periph.h>
#include <cam/cam_xpt_periph.h>
#include <cam/scsi/scsi_message.h>
#ifndef _KERNEL
#include <cam/scsi/scsi_da.h>
#endif /* !_KERNEL */
#ifdef _KERNEL
typedef enum {
DA_STATE_PROBE,
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
DA_STATE_PROBE2,
DA_STATE_NORMAL
} da_state;
typedef enum {
DA_FLAG_PACK_INVALID = 0x001,
DA_FLAG_NEW_PACK = 0x002,
DA_FLAG_PACK_LOCKED = 0x004,
DA_FLAG_PACK_REMOVABLE = 0x008,
DA_FLAG_TAGGED_QUEUING = 0x010,
DA_FLAG_NEED_OTAG = 0x020,
DA_FLAG_WENT_IDLE = 0x040,
DA_FLAG_RETRY_UA = 0x080,
DA_FLAG_OPEN = 0x100,
DA_FLAG_SCTX_INIT = 0x200
} da_flags;
typedef enum {
DA_Q_NONE = 0x00,
DA_Q_NO_SYNC_CACHE = 0x01,
DA_Q_NO_6_BYTE = 0x02,
DA_Q_NO_PREVENT = 0x04
} da_quirks;
typedef enum {
DA_CCB_PROBE = 0x01,
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
DA_CCB_PROBE2 = 0x02,
DA_CCB_BUFFER_IO = 0x03,
DA_CCB_WAITING = 0x04,
DA_CCB_DUMP = 0x05,
DA_CCB_TYPE_MASK = 0x0F,
DA_CCB_RETRY_UA = 0x10
} da_ccb_state;
/* Offsets into our private area for storing information */
#define ccb_state ppriv_field0
#define ccb_bp ppriv_ptr1
struct disk_params {
u_int8_t heads;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
u_int32_t cylinders;
u_int8_t secs_per_track;
u_int32_t secsize; /* Number of bytes/sector */
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
u_int64_t sectors; /* total number sectors */
};
struct da_softc {
struct bio_queue_head bio_queue;
SLIST_ENTRY(da_softc) links;
LIST_HEAD(, ccb_hdr) pending_ccbs;
da_state state;
da_flags flags;
da_quirks quirks;
int minimum_cmd_size;
int ordered_tag_count;
int outstanding_cmds;
struct disk_params params;
struct disk *disk;
union ccb saved_ccb;
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
struct task sysctl_task;
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
struct sysctl_ctx_list sysctl_ctx;
struct sysctl_oid *sysctl_tree;
};
struct da_quirk_entry {
struct scsi_inquiry_pattern inq_pat;
da_quirks quirks;
};
static const char quantum[] = "QUANTUM";
static const char microp[] = "MICROP";
static struct da_quirk_entry da_quirk_table[] =
{
2003-08-25 18:14:43 +00:00
/* SPI, FC devices */
{
/*
* Fujitsu M2513A MO drives.
* Tested devices: M2513A2 firmware versions 1200 & 1300.
* (dip switch selects whether T_DIRECT or T_OPTICAL device)
* Reported by: W.Scholten <whs@xs4all.nl>
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/* See above. */
{T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* This particular Fujitsu drive doesn't like the
* synchronize cache command.
* Reported by: Tom Jackson <toj@gorilla.net>
*/
{T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* This drive doesn't like the synchronize cache command
* either. Reported by: Matthew Jacob <mjacob@feral.com>
* in NetBSD PR kern/6027, August 24, 1998.
*/
{T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* This drive doesn't like the synchronize cache command
* either. Reported by: Hellmuth Michaelis (hm@kts.org)
* (PR 8882).
*/
{T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Doesn't like the synchronize cache command.
* Reported by: Blaz Zupan <blaz@gold.amis.net>
*/
{T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Doesn't like the synchronize cache command.
* Reported by: Blaz Zupan <blaz@gold.amis.net>
*/
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Doesn't like the synchronize cache command.
*/
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Doesn't like the synchronize cache command.
* Reported by: walter@pelissero.de
*/
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Doesn't work correctly with 6 byte reads/writes.
* Returns illegal request, and points to byte 9 of the
* 6-byte CDB.
* Reported by: Adam McDougall <bsdx@spawnet.com>
*/
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
/*quirks*/ DA_Q_NO_6_BYTE
},
{
/* See above. */
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
/*quirks*/ DA_Q_NO_6_BYTE
},
{
/*
* Doesn't like the synchronize cache command.
* Reported by: walter@pelissero.de
*/
{T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* The CISS RAID controllers do not support SYNC_CACHE
*/
{T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
2003-08-25 18:14:43 +00:00
/* USB mass storage devices supported by umass(4) */
{
/*
* EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
* PR: kern/51675
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Power Quotient Int. (PQI) USB flash key
* PR: kern/53067
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Creative Nomad MUVO mp3 player (USB)
* PR: kern/53094
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
},
{
/*
* Jungsoft NEXDISK USB flash key
* PR: kern/54737
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* FreeDik USB Mini Data Drive
* PR: kern/54786
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "FreeDik*", "Mini Data Drive",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Sigmatel USB Flash MP3 Player
* PR: kern/57046
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
},
{
/*
* Neuros USB Digital Audio Computer
* PR: kern/63645
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* SEAGRAND NP-900 MP3 Player
* PR: kern/64563
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
},
{
/*
* iRiver iFP MP3 player (with UMS Firmware)
* PR: kern/54881, i386/63941, kern/66124
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "iRiver", "iFP*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
* PR: kern/70158
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* ZICPlay USB MP3 Player with FM
* PR: kern/75057
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
2005-05-05 18:48:41 +00:00
{
/*
* TEAC USB floppy mechanisms
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"},
/*quirks*/ DA_Q_NO_SYNC_CACHE
},
2005-06-09 17:35:04 +00:00
{
/*
* Kingston DataTraveler II+ USB Pen-Drive.
* Reported by: Pawel Jakub Dawidek <pjd@FreeBSD.org>
*/
2005-12-19 03:43:48 +00:00
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
2005-06-09 17:35:04 +00:00
},
{
/*
* Motorola E398 Mobile Phone (TransFlash memory card).
* Reported by: Wojciech A. Koszek <dunstan@FreeBSD.czest.pl>
* PR: usb/89889
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Motorola" , "Motorola Phone",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Qware BeatZkey! Pro
* PR: usb/79164
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "GENERIC", "USB DISK DEVICE",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Time DPA20B 1GB MP3 Player
* PR: usb/81846
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "USB2.0*", "(FS) FLASH DISK*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Samsung USB key 128Mb
* PR: usb/90081
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "USB-DISK", "FreeDik-FlashUsb",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Kingston DataTraveler 2.0 USB Flash memory.
* PR: usb/89196
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler 2.0",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Creative MUVO Slim mp3 player (USB)
* PR: usb/86131
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
},
{
/*
* United MP5512 Portable MP3 Player (2-in-1 USB DISK/MP3)
* PR: usb/80487
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "MUSIC DISK",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* SanDisk Micro Cruzer 128MB
* PR: usb/75970
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk" , "Micro Cruzer",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* TOSHIBA TransMemory USB sticks
* PR: kern/94660
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "TOSHIBA", "TransMemory",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* PNY USB Flash keys
* PR: usb/75578, usb/72344, usb/65436
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Genesys 6-in-1 Card Reader
* PR: usb/94647
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Rekam Digital CAMERA
* PR: usb/98713
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "CAMERA*", "4MP-9J6*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* iRiver H10 MP3 player
* PR: usb/102547
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "H10*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* X-Micro Flash Disk
* PR: usb/96901
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "X-Micro", "Flash Disk",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* EasyMP3 EM732X USB 2.0 Flash MP3 Player
* PR: usb/96546
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "EM732X", "MP3 Player*",
"1.0"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
};
static disk_strategy_t dastrategy;
static dumper_t dadump;
static periph_init_t dainit;
static void daasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg);
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
static void dasysctlinit(void *context, int pending);
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
static periph_ctor_t daregister;
static periph_dtor_t dacleanup;
static periph_start_t dastart;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
static periph_oninv_t daoninvalidate;
static void dadone(struct cam_periph *periph,
union ccb *done_ccb);
static int daerror(union ccb *ccb, u_int32_t cam_flags,
u_int32_t sense_flags);
static void daprevent(struct cam_periph *periph, int action);
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
static int dagetcapacity(struct cam_periph *periph);
static void dasetgeom(struct cam_periph *periph, uint32_t block_len,
uint64_t maxsector);
static timeout_t dasendorderedtag;
static void dashutdown(void *arg, int howto);
#ifndef DA_DEFAULT_TIMEOUT
#define DA_DEFAULT_TIMEOUT 60 /* Timeout in seconds */
#endif
#ifndef DA_DEFAULT_RETRY
#define DA_DEFAULT_RETRY 4
#endif
#ifndef DA_DEFAULT_SEND_ORDERED
#define DA_DEFAULT_SEND_ORDERED 1
#endif
static int da_retry_count = DA_DEFAULT_RETRY;
static int da_default_timeout = DA_DEFAULT_TIMEOUT;
static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
"CAM Direct Access Disk driver");
SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
&da_retry_count, 0, "Normal I/O retry count");
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
&da_default_timeout, 0, "Normal I/O timeout (in seconds)");
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
SYSCTL_INT(_kern_cam_da, OID_AUTO, da_send_ordered, CTLFLAG_RW,
&da_send_ordered, 0, "Send Ordered Tags");
TUNABLE_INT("kern.cam.da.da_send_ordered", &da_send_ordered);
/*
* DA_ORDEREDTAG_INTERVAL determines how often, relative
* to the default timeout, we check to see whether an ordered
* tagged transaction is appropriate to prevent simple tag
* starvation. Since we'd like to ensure that there is at least
* 1/2 of the timeout length left for a starved transaction to
* complete after we've sent an ordered tag, we must poll at least
* four times in every timeout period. This takes care of the worst
* case where a starved transaction starts during an interval that
* meets the requirement "don't send an ordered tag" test so it takes
* us two intervals to determine that a tag must be sent.
*/
#ifndef DA_ORDEREDTAG_INTERVAL
#define DA_ORDEREDTAG_INTERVAL 4
#endif
static struct periph_driver dadriver =
{
dainit, "da",
TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
};
PERIPHDRIVER_DECLARE(da, dadriver);
static SLIST_HEAD(,da_softc) softc_list;
static int
daopen(struct disk *dp)
{
struct cam_periph *periph;
struct da_softc *softc;
int unit;
int error;
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
int s;
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
s = splsoftcam();
periph = (struct cam_periph *)dp->d_drv1;
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
if (periph == NULL) {
splx(s);
return (ENXIO);
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
}
unit = periph->unit_number;
softc = (struct da_softc *)periph->softc;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
("daopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit,
unit));
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0)
return (error); /* error code from tsleep */
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
return(ENXIO);
softc->flags |= DA_FLAG_OPEN;
if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
Some fixes for the CD and DA drivers from bde. (and some of my own as well) Among them: [ cd driver ] 1. Old labeling code was still there. 2. Error handling for dsopen() was broken (no test for the `error' returned by dsopen(); bogus test of an `error' that is known to be 0). 3. cdopen() closed the physical device after certain errors although there may still be open partitions on it. 4. cdclose() closed the physical device although there may still be open partitions on it. 5. Some printf format fixes was incomplete or missing. 6. cdioctl() truncated unit numbers mod 256. 7. cdioctl() was missing locking. [ da driver ] 1. daclose() closed the physical device although there may still be open partitions on it. This was fixed many years ago in sd.c rev.1.57. 2. A minor optimization (the dk_slices != NULL test) in sdopen() became uglier in daopen(). It is not worth doing. da only regressed compared with od and my version of sd, since I never committed the change to sd. daopen() should probably do less if some partition is already open. This is not addressed by the diffs. [ ... ] 5. "opt_hw_wdog.h" was not included, so the HW_WDOG code was unreachable. - Added a getdev CCB call in the cdopen() and daopen() calls so that the vendor name and device name are available for the disklabel. (suggested by bde) - Removed vestigal devfs support in both drivers, since we can't properly work with devfs yet. (ask bde for details on this) - Cleaned up the probe code in both drivers in the failure cases. There were a number of things wrong here. The peripheral driver instances weren't getting properly cleaned up. Sometimes the wrong probe message would get printed out (with the failure message appended), so it wasn't very clear that we failed to attach. SCSI sense information was printed, even when the error in question wasn't a SCSI error. I put similar fixes into the changer driver in revision 1.2 of scsi_ch.c. Reviewed by: gibbs Submitted by: bde (partially)
1998-10-07 02:57:57 +00:00
/* Invalidate our pack information. */
softc->flags &= ~DA_FLAG_PACK_INVALID;
}
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
splx(s);
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
error = dagetcapacity(periph);
if (error == 0) {
Some fixes for the CD and DA drivers from bde. (and some of my own as well) Among them: [ cd driver ] 1. Old labeling code was still there. 2. Error handling for dsopen() was broken (no test for the `error' returned by dsopen(); bogus test of an `error' that is known to be 0). 3. cdopen() closed the physical device after certain errors although there may still be open partitions on it. 4. cdclose() closed the physical device although there may still be open partitions on it. 5. Some printf format fixes was incomplete or missing. 6. cdioctl() truncated unit numbers mod 256. 7. cdioctl() was missing locking. [ da driver ] 1. daclose() closed the physical device although there may still be open partitions on it. This was fixed many years ago in sd.c rev.1.57. 2. A minor optimization (the dk_slices != NULL test) in sdopen() became uglier in daopen(). It is not worth doing. da only regressed compared with od and my version of sd, since I never committed the change to sd. daopen() should probably do less if some partition is already open. This is not addressed by the diffs. [ ... ] 5. "opt_hw_wdog.h" was not included, so the HW_WDOG code was unreachable. - Added a getdev CCB call in the cdopen() and daopen() calls so that the vendor name and device name are available for the disklabel. (suggested by bde) - Removed vestigal devfs support in both drivers, since we can't properly work with devfs yet. (ask bde for details on this) - Cleaned up the probe code in both drivers in the failure cases. There were a number of things wrong here. The peripheral driver instances weren't getting properly cleaned up. Sometimes the wrong probe message would get printed out (with the failure message appended), so it wasn't very clear that we failed to attach. SCSI sense information was printed, even when the error in question wasn't a SCSI error. I put similar fixes into the changer driver in revision 1.2 of scsi_ch.c. Reviewed by: gibbs Submitted by: bde (partially)
1998-10-07 02:57:57 +00:00
softc->disk->d_sectorsize = softc->params.secsize;
softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
/* XXX: these are not actually "firmware" values, so they may be wrong */
softc->disk->d_fwsectors = softc->params.secs_per_track;
softc->disk->d_fwheads = softc->params.heads;
softc->disk->d_devstat->block_size = softc->params.secsize;
softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
}
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
if (error == 0) {
if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
(softc->quirks & DA_Q_NO_PREVENT) == 0)
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
daprevent(periph, PR_PREVENT);
} else {
softc->flags &= ~DA_FLAG_OPEN;
cam_periph_release(periph);
}
cam_periph_unlock(periph);
return (error);
}
static int
daclose(struct disk *dp)
{
struct cam_periph *periph;
struct da_softc *softc;
int error;
periph = (struct cam_periph *)dp->d_drv1;
if (periph == NULL)
return (ENXIO);
softc = (struct da_softc *)periph->softc;
if ((error = cam_periph_lock(periph, PRIBIO)) != 0) {
return (error); /* error code from tsleep */
}
if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
union ccb *ccb;
ccb = cam_periph_getccb(periph, /*priority*/1);
scsi_synchronize_cache(&ccb->csio,
/*retries*/1,
/*cbfcnp*/dadone,
MSG_SIMPLE_Q_TAG,
/*begin_lba*/0,/* Cover the whole disk */
/*lb_count*/0,
SSD_FULL_SIZE,
5 * 60 * 1000);
cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
1998-12-23 16:48:17 +00:00
/*sense_flags*/SF_RETRY_UA,
softc->disk->d_devstat);
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
CAM_SCSI_STATUS_ERROR) {
int asc, ascq;
int sense_key, error_code;
scsi_extract_sense(&ccb->csio.sense_data,
&error_code,
&sense_key,
&asc, &ascq);
if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
scsi_sense_print(&ccb->csio);
} else {
xpt_print(periph->path, "Synchronize cache "
"failed, status == 0x%x, scsi status == "
"0x%x\n", ccb->csio.ccb_h.status,
ccb->csio.scsi_status);
}
}
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(ccb->ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
xpt_release_ccb(ccb);
}
if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
daprevent(periph, PR_ALLOW);
/*
* If we've got removeable media, mark the blocksize as
* unavailable, since it could change when new media is
* inserted.
*/
softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
}
softc->flags &= ~DA_FLAG_OPEN;
cam_periph_unlock(periph);
cam_periph_release(periph);
return (0);
}
/*
* Actually translate the requested transfer into one the physical driver
* can understand. The transfer is described by a buf and will include
* only one physical transfer.
*/
static void
dastrategy(struct bio *bp)
{
struct cam_periph *periph;
struct da_softc *softc;
int s;
periph = (struct cam_periph *)bp->bio_disk->d_drv1;
if (periph == NULL) {
biofinish(bp, NULL, ENXIO);
return;
}
softc = (struct da_softc *)periph->softc;
#if 0
/*
* check it's not too big a transfer for our adapter
*/
scsi_minphys(bp,&sd_switch);
#endif
/*
* Mask interrupts so that the pack cannot be invalidated until
* after we are in the queue. Otherwise, we might not properly
* clean up one of the buffers.
*/
s = splbio();
/*
* If the device has been made invalid, error out
*/
if ((softc->flags & DA_FLAG_PACK_INVALID)) {
splx(s);
biofinish(bp, NULL, ENXIO);
return;
}
/*
* Place it in the queue of disk activities for this disk
*/
bioq_disksort(&softc->bio_queue, bp);
splx(s);
/*
* Schedule ourselves for performing the work.
*/
xpt_schedule(periph, /* XXX priority */1);
return;
}
static int
dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
{
struct cam_periph *periph;
struct da_softc *softc;
u_int secsize;
struct ccb_scsiio csio;
struct disk *dp;
dp = arg;
periph = dp->d_drv1;
if (periph == NULL)
return (ENXIO);
softc = (struct da_softc *)periph->softc;
secsize = softc->params.secsize;
if ((softc->flags & DA_FLAG_PACK_INVALID) != 0)
return (ENXIO);
if (length > 0) {
xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
csio.ccb_h.ccb_state = DA_CCB_DUMP;
scsi_read_write(&csio,
/*retries*/1,
dadone,
MSG_ORDERED_Q_TAG,
/*read*/FALSE,
/*byte2*/0,
/*minimum_cmd_size*/ softc->minimum_cmd_size,
offset / secsize,
length / secsize,
/*data_ptr*/(u_int8_t *) virtual,
/*dxfer_len*/length,
/*sense_len*/SSD_FULL_SIZE,
DA_DEFAULT_TIMEOUT * 1000);
xpt_polled_action((union ccb *)&csio);
if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
printf("Aborting dump due to I/O error.\n");
if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
CAM_SCSI_STATUS_ERROR)
scsi_sense_print(&csio);
else
printf("status == 0x%x, scsi status == 0x%x\n",
csio.ccb_h.status, csio.scsi_status);
return(EIO);
}
return(0);
}
/*
* Sync the disk cache contents to the physical media.
*/
if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
csio.ccb_h.ccb_state = DA_CCB_DUMP;
scsi_synchronize_cache(&csio,
/*retries*/1,
/*cbfcnp*/dadone,
MSG_SIMPLE_Q_TAG,
/*begin_lba*/0,/* Cover the whole disk */
/*lb_count*/0,
SSD_FULL_SIZE,
5 * 60 * 1000);
xpt_polled_action((union ccb *)&csio);
if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
CAM_SCSI_STATUS_ERROR) {
int asc, ascq;
int sense_key, error_code;
scsi_extract_sense(&csio.sense_data,
&error_code,
&sense_key,
&asc, &ascq);
if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
scsi_sense_print(&csio);
} else {
xpt_print(periph->path, "Synchronize cache "
"failed, status == 0x%x, scsi status == "
"0x%x\n", csio.ccb_h.status,
csio.scsi_status);
}
}
}
return (0);
}
static void
dainit(void)
{
cam_status status;
struct cam_path *path;
SLIST_INIT(&softc_list);
/*
* Install a global async callback. This callback will
* receive async callbacks like "new device found".
*/
status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
if (status == CAM_REQ_CMP) {
struct ccb_setasync csa;
xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
csa.ccb_h.func_code = XPT_SASYNC_CB;
csa.event_enable = AC_FOUND_DEVICE;
csa.callback = daasync;
csa.callback_arg = NULL;
xpt_action((union ccb *)&csa);
status = csa.ccb_h.status;
xpt_free_path(path);
}
if (status != CAM_REQ_CMP) {
printf("da: Failed to attach master async callback "
"due to status 0x%x!\n", status);
} else if (da_send_ordered) {
/*
* Schedule a periodic event to occasionally send an
* ordered tag to a device.
*/
timeout(dasendorderedtag, NULL,
(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
/* Register our shutdown event handler */
if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown,
2003-01-06 19:30:21 +00:00
NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
printf("dainit: shutdown event registration failed!\n");
}
}
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
static void
daoninvalidate(struct cam_periph *periph)
{
int s;
struct da_softc *softc;
struct ccb_setasync csa;
softc = (struct da_softc *)periph->softc;
/*
* De-register any async callbacks.
*/
xpt_setup_ccb(&csa.ccb_h, periph->path,
/* priority */ 5);
csa.ccb_h.func_code = XPT_SASYNC_CB;
csa.event_enable = 0;
csa.callback = daasync;
csa.callback_arg = periph;
xpt_action((union ccb *)&csa);
softc->flags |= DA_FLAG_PACK_INVALID;
/*
* Although the oninvalidate() routines are always called at
* splsoftcam, we need to be at splbio() here to keep the buffer
* queue from being modified while we traverse it.
*/
s = splbio();
/*
* Return all queued I/O with ENXIO.
* XXX Handle any transactions queued to the card
* with XPT_ABORT_CCB.
*/
bioq_flush(&softc->bio_queue, NULL, ENXIO);
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
splx(s);
SLIST_REMOVE(&softc_list, softc, da_softc, links);
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
disk_gone(softc->disk);
xpt_print(periph->path, "lost device\n");
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
}
static void
dacleanup(struct cam_periph *periph)
{
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
struct da_softc *softc;
softc = (struct da_softc *)periph->softc;
xpt_print(periph->path, "removing device entry\n");
/*
* If we can't free the sysctl tree, oh well...
*/
if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
&& sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
xpt_print(periph->path, "can't remove sysctl context\n");
}
disk_destroy(softc->disk);
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
free(softc, M_DEVBUF);
}
static void
daasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg)
{
struct cam_periph *periph;
periph = (struct cam_periph *)callback_arg;
switch (code) {
case AC_FOUND_DEVICE:
{
struct ccb_getdev *cgd;
cam_status status;
cgd = (struct ccb_getdev *)arg;
if (cgd == NULL)
break;
if (SID_TYPE(&cgd->inq_data) != T_DIRECT
&& SID_TYPE(&cgd->inq_data) != T_RBC
&& SID_TYPE(&cgd->inq_data) != T_OPTICAL)
break;
/*
* Allocate a peripheral instance for
* this device and start the probe
* process.
*/
Fix a problem with the way we handled device invalidation when attaching to a device failed. In theory, the same steps that happen when we get an AC_LOST_DEVICE async notification should have been taken when a driver fails to attach. In practice, that wasn't the case. This only affected the da, cd and ch drivers, but the fix affects all peripheral drivers. There were several possible problems: - In the da driver, we didn't remove the peripheral's softc from the da driver's linked list of softcs. Once the peripheral and softc got removed, we'd get a kernel panic the next time the timeout routine called dasendorderedtag(). - In the da, cd and possibly ch drivers, we didn't remove the peripheral's devstat structure from the devstat queue. Once the peripheral and softc were removed, this could cause a panic if anyone tried to access device statistics. (one component of the linked list wouldn't exist anymore) - In the cd driver, we didn't take the peripheral off the changer run queue if it was scheduled to run. In practice, it's highly unlikely, and maybe impossible that the peripheral would have been on the changer run queue at that stage of the probe process. The fix is: - Add a new peripheral callback function (the "oninvalidate" function) that is called the first time cam_periph_invalidate() is called for a peripheral. - Create new foooninvalidate() routines for each peripheral driver. This routine is always called at splsoftcam(), and contains all the stuff that used to be in the AC_LOST_DEVICE case of the async callback handler. - Move the devstat cleanup call to the destructor/cleanup routines, since some of the drivers do I/O in their close routines. - Make sure that when we're flushing the buffer queue, we traverse it at splbio(). - Add a check for the invalid flag in the pt driver's open routine. Reviewed by: gibbs
1998-10-22 22:16:56 +00:00
status = cam_periph_alloc(daregister, daoninvalidate,
dacleanup, dastart,
"da", CAM_PERIPH_BIO,
cgd->ccb_h.path, daasync,
AC_FOUND_DEVICE, cgd);
if (status != CAM_REQ_CMP
&& status != CAM_REQ_INPROG)
printf("daasync: Unable to attach to new device "
"due to status 0x%x\n", status);
break;
}
case AC_SENT_BDR:
case AC_BUS_RESET:
{
struct da_softc *softc;
struct ccb_hdr *ccbh;
int s;
softc = (struct da_softc *)periph->softc;
s = splsoftcam();
/*
* Don't fail on the expected unit attention
* that will occur.
*/
softc->flags |= DA_FLAG_RETRY_UA;
LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
ccbh->ccb_state |= DA_CCB_RETRY_UA;
splx(s);
/* FALLTHROUGH*/
}
default:
cam_periph_async(periph, code, path, arg);
break;
}
}
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
static void
dasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct da_softc *softc;
char tmpstr[80], tmpstr2[80];
periph = (struct cam_periph *)context;
softc = (struct da_softc *)periph->softc;
snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
mtx_lock(&Giant);
sysctl_ctx_init(&softc->sysctl_ctx);
softc->flags |= DA_FLAG_SCTX_INIT;
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
CTLFLAG_RD, 0, tmpstr);
if (softc->sysctl_tree == NULL) {
printf("dasysctlinit: unable to allocate sysctl tree\n");
mtx_unlock(&Giant);
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
return;
}
/*
* Now register the sysctl handler, so the user can the value on
* the fly.
*/
SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
&softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
"Minimum CDB size");
mtx_unlock(&Giant);
}
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
static int
dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
{
int error, value;
value = *(int *)arg1;
error = sysctl_handle_int(oidp, &value, 0, req);
if ((error != 0)
|| (req->newptr == NULL))
return (error);
/*
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
* Acceptable values here are 6, 10, 12 or 16.
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
*/
if (value < 6)
value = 6;
else if ((value > 6)
&& (value <= 10))
value = 10;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
else if ((value > 10)
&& (value <= 12))
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
value = 12;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
else if (value > 12)
value = 16;
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
*(int *)arg1 = value;
return (0);
}
static cam_status
daregister(struct cam_periph *periph, void *arg)
{
int s;
struct da_softc *softc;
struct ccb_setasync csa;
struct ccb_pathinq cpi;
struct ccb_getdev *cgd;
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
char tmpstr[80];
caddr_t match;
cgd = (struct ccb_getdev *)arg;
if (periph == NULL) {
printf("daregister: periph was NULL!!\n");
return(CAM_REQ_CMP_ERR);
}
if (cgd == NULL) {
printf("daregister: no getdev CCB, can't register device\n");
return(CAM_REQ_CMP_ERR);
}
softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF,
M_NOWAIT|M_ZERO);
if (softc == NULL) {
printf("daregister: Unable to probe new device. "
"Unable to allocate softc\n");
return(CAM_REQ_CMP_ERR);
}
LIST_INIT(&softc->pending_ccbs);
softc->state = DA_STATE_PROBE;
bioq_init(&softc->bio_queue);
if (SID_IS_REMOVABLE(&cgd->inq_data))
softc->flags |= DA_FLAG_PACK_REMOVABLE;
if ((cgd->inq_data.flags & SID_CmdQue) != 0)
softc->flags |= DA_FLAG_TAGGED_QUEUING;
periph->softc = softc;
/*
* See if this device has any quirks.
*/
match = cam_quirkmatch((caddr_t)&cgd->inq_data,
(caddr_t)da_quirk_table,
sizeof(da_quirk_table)/sizeof(*da_quirk_table),
sizeof(*da_quirk_table), scsi_inquiry_match);
if (match != NULL)
softc->quirks = ((struct da_quirk_entry *)match)->quirks;
else
softc->quirks = DA_Q_NONE;
/* Check if the SIM does not want 6 byte commands */
xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
cpi.ccb_h.func_code = XPT_PATH_INQ;
xpt_action((union ccb *)&cpi);
if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
softc->quirks |= DA_Q_NO_6_BYTE;
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
/*
* RBC devices don't have to support READ(6), only READ(10).
*/
if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
softc->minimum_cmd_size = 10;
else
softc->minimum_cmd_size = 6;
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
/*
* Load the user's default, if any.
*/
snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
periph->unit_number);
TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
/*
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
* 6, 10, 12 and 16 are the currently permissible values.
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
*/
if (softc->minimum_cmd_size < 6)
softc->minimum_cmd_size = 6;
else if ((softc->minimum_cmd_size > 6)
&& (softc->minimum_cmd_size <= 10))
softc->minimum_cmd_size = 10;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
else if ((softc->minimum_cmd_size > 10)
&& (softc->minimum_cmd_size <= 12))
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
softc->minimum_cmd_size = 12;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
else if (softc->minimum_cmd_size > 12)
softc->minimum_cmd_size = 16;
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
/*
* Block our timeout handler while we
* add this softc to the dev list.
*/
s = splsoftclock();
SLIST_INSERT_HEAD(&softc_list, softc, links);
splx(s);
/*
* Register this media as a disk
*/
softc->disk = disk_alloc();
softc->disk->d_open = daopen;
softc->disk->d_close = daclose;
softc->disk->d_strategy = dastrategy;
softc->disk->d_dump = dadump;
softc->disk->d_name = "da";
softc->disk->d_drv1 = periph;
softc->disk->d_maxsize = DFLTPHYS; /* XXX: probably not arbitrary */
softc->disk->d_unit = periph->unit_number;
softc->disk->d_flags = DISKFLAG_NEEDSGIANT;
if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
disk_create(softc->disk, DISK_VERSION);
/*
* Add async callbacks for bus reset and
* bus device reset calls. I don't bother
* checking if this fails as, in most cases,
* the system will function just fine without
* them and the only alternative would be to
* not attach the device on failure.
*/
xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5);
csa.ccb_h.func_code = XPT_SASYNC_CB;
csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE;
csa.callback = daasync;
csa.callback_arg = periph;
xpt_action((union ccb *)&csa);
/*
* Lock this peripheral until we are setup.
* This first call can't block
*/
(void)cam_periph_lock(periph, PRIBIO);
xpt_schedule(periph, /*priority*/5);
return(CAM_REQ_CMP);
}
static void
dastart(struct cam_periph *periph, union ccb *start_ccb)
{
struct da_softc *softc;
softc = (struct da_softc *)periph->softc;
switch (softc->state) {
case DA_STATE_NORMAL:
{
/* Pull a buffer from the queue and get going on it */
struct bio *bp;
int s;
/*
* See if there is a buf with work for us to do..
*/
s = splbio();
bp = bioq_first(&softc->bio_queue);
if (periph->immediate_priority <= periph->pinfo.priority) {
CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
("queuing for immediate ccb\n"));
start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
periph_links.sle);
periph->immediate_priority = CAM_PRIORITY_NONE;
splx(s);
wakeup(&periph->ccb_list);
} else if (bp == NULL) {
splx(s);
xpt_release_ccb(start_ccb);
} else {
int oldspl;
u_int8_t tag_code;
bioq_remove(&softc->bio_queue, bp);
2002-02-22 09:18:46 +00:00
if ((softc->flags & DA_FLAG_NEED_OTAG) != 0) {
softc->flags &= ~DA_FLAG_NEED_OTAG;
softc->ordered_tag_count++;
tag_code = MSG_ORDERED_Q_TAG;
} else {
tag_code = MSG_SIMPLE_Q_TAG;
}
switch (bp->bio_cmd) {
case BIO_READ:
case BIO_WRITE:
scsi_read_write(&start_ccb->csio,
/*retries*/da_retry_count,
/*cbfcnp*/dadone,
/*tag_action*/tag_code,
/*read_op*/bp->bio_cmd == BIO_READ,
/*byte2*/0,
softc->minimum_cmd_size,
/*lba*/bp->bio_pblkno,
/*block_count*/bp->bio_bcount /
softc->params.secsize,
/*data_ptr*/ bp->bio_data,
/*dxfer_len*/ bp->bio_bcount,
/*sense_len*/SSD_FULL_SIZE,
/*timeout*/da_default_timeout*1000);
break;
case BIO_FLUSH:
scsi_synchronize_cache(&start_ccb->csio,
/*retries*/1,
/*cbfcnp*/dadone,
MSG_SIMPLE_Q_TAG,
/*begin_lba*/0,/* Cover the whole disk */
/*lb_count*/0,
SSD_FULL_SIZE,
/*timeout*/da_default_timeout*1000);
break;
}
start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
/*
* Block out any asyncronous callbacks
* while we touch the pending ccb list.
*/
oldspl = splcam();
LIST_INSERT_HEAD(&softc->pending_ccbs,
&start_ccb->ccb_h, periph_links.le);
softc->outstanding_cmds++;
splx(oldspl);
/* We expect a unit attention from this device */
if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
softc->flags &= ~DA_FLAG_RETRY_UA;
}
start_ccb->ccb_h.ccb_bp = bp;
bp = bioq_first(&softc->bio_queue);
splx(s);
xpt_action(start_ccb);
}
if (bp != NULL) {
/* Have more work to do, so ensure we stay scheduled */
xpt_schedule(periph, /* XXX priority */1);
}
break;
}
case DA_STATE_PROBE:
{
struct ccb_scsiio *csio;
struct scsi_read_capacity_data *rcap;
rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcap),
M_TEMP,
M_NOWAIT);
if (rcap == NULL) {
printf("dastart: Couldn't malloc read_capacity data\n");
/* da_free_periph??? */
break;
}
csio = &start_ccb->csio;
scsi_read_capacity(csio,
/*retries*/4,
dadone,
MSG_SIMPLE_Q_TAG,
rcap,
SSD_FULL_SIZE,
/*timeout*/5000);
start_ccb->ccb_h.ccb_bp = NULL;
start_ccb->ccb_h.ccb_state = DA_CCB_PROBE;
xpt_action(start_ccb);
break;
}
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
case DA_STATE_PROBE2:
{
struct ccb_scsiio *csio;
struct scsi_read_capacity_data_long *rcaplong;
rcaplong = (struct scsi_read_capacity_data_long *)
malloc(sizeof(*rcaplong), M_TEMP, M_NOWAIT);
if (rcaplong == NULL) {
printf("dastart: Couldn't malloc read_capacity data\n");
/* da_free_periph??? */
break;
}
csio = &start_ccb->csio;
scsi_read_capacity_16(csio,
/*retries*/ 4,
/*cbfcnp*/ dadone,
/*tag_action*/ MSG_SIMPLE_Q_TAG,
/*lba*/ 0,
/*reladr*/ 0,
/*pmi*/ 0,
rcaplong,
/*sense_len*/ SSD_FULL_SIZE,
/*timeout*/ 60000);
start_ccb->ccb_h.ccb_bp = NULL;
start_ccb->ccb_h.ccb_state = DA_CCB_PROBE2;
xpt_action(start_ccb);
break;
}
}
}
static int
cmd6workaround(union ccb *ccb)
{
struct scsi_rw_6 cmd6;
struct scsi_rw_10 *cmd10;
struct da_softc *softc;
u_int8_t *cdb;
int frozen;
cdb = ccb->csio.cdb_io.cdb_bytes;
/* Translation only possible if CDB is an array and cmd is R/W6 */
if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
(*cdb != READ_6 && *cdb != WRITE_6))
return 0;
xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, "
"increasing minimum_cmd_size to 10.\n");
softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
softc->minimum_cmd_size = 10;
bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
cmd10 = (struct scsi_rw_10 *)cdb;
cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
cmd10->byte2 = 0;
scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
cmd10->reserved = 0;
scsi_ulto2b(cmd6.length, cmd10->length);
cmd10->control = cmd6.control;
ccb->csio.cdb_len = sizeof(*cmd10);
/* Requeue request, unfreezing queue if necessary */
frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_action(ccb);
if (frozen) {
cam_release_devq(ccb->ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
}
return (ERESTART);
}
static void
dadone(struct cam_periph *periph, union ccb *done_ccb)
{
struct da_softc *softc;
struct ccb_scsiio *csio;
softc = (struct da_softc *)periph->softc;
csio = &done_ccb->csio;
switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
case DA_CCB_BUFFER_IO:
{
struct bio *bp;
int oldspl;
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
int error;
int s;
int sf;
if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
sf = SF_RETRY_UA;
else
sf = 0;
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
error = daerror(done_ccb, CAM_RETRY_SELTO, sf);
if (error == ERESTART) {
/*
* A retry was scheuled, so
* just return.
*/
return;
}
if (error != 0) {
s = splbio();
if (error == ENXIO) {
/*
* Catastrophic error. Mark our pack as
* invalid.
*/
/*
* XXX See if this is really a media
* XXX change first?
*/
xpt_print(periph->path,
"Invalidating pack\n");
softc->flags |= DA_FLAG_PACK_INVALID;
}
/*
* return all queued I/O with EIO, so that
* the client can retry these I/Os in the
* proper order should it attempt to recover.
*/
bioq_flush(&softc->bio_queue, NULL, EIO);
splx(s);
bp->bio_error = error;
bp->bio_resid = bp->bio_bcount;
bp->bio_flags |= BIO_ERROR;
} else {
bp->bio_resid = csio->resid;
bp->bio_error = 0;
if (bp->bio_resid != 0)
bp->bio_flags |= BIO_ERROR;
}
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(done_ccb->ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
} else {
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
panic("REQ_CMP with QFRZN");
bp->bio_resid = csio->resid;
if (csio->resid > 0)
bp->bio_flags |= BIO_ERROR;
}
/*
* Block out any asyncronous callbacks
* while we touch the pending ccb list.
*/
oldspl = splcam();
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
softc->outstanding_cmds--;
if (softc->outstanding_cmds == 0)
softc->flags |= DA_FLAG_WENT_IDLE;
splx(oldspl);
biodone(bp);
break;
}
case DA_CCB_PROBE:
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
case DA_CCB_PROBE2:
{
struct scsi_read_capacity_data *rdcap;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
struct scsi_read_capacity_data_long *rcaplong;
char announce_buf[80];
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
rdcap = NULL;
rcaplong = NULL;
if (softc->state == DA_STATE_PROBE)
rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
else
rcaplong = (struct scsi_read_capacity_data_long *)
csio->data_ptr;
if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
struct disk_params *dp;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
uint32_t block_size;
uint64_t maxsector;
if (softc->state == DA_STATE_PROBE) {
block_size = scsi_4btoul(rdcap->length);
maxsector = scsi_4btoul(rdcap->addr);
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
/*
* According to SBC-2, if the standard 10
* byte READ CAPACITY command returns 2^32,
* we should issue the 16 byte version of
* the command, since the device in question
* has more sectors than can be represented
* with the short version of the command.
*/
if (maxsector == 0xffffffff) {
softc->state = DA_STATE_PROBE2;
free(rdcap, M_TEMP);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, /*priority*/5);
return;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
}
} else {
block_size = scsi_4btoul(rcaplong->length);
maxsector = scsi_8btou64(rcaplong->addr);
}
/*
* Because GEOM code just will panic us if we
* give them an 'illegal' value we'll avoid that
* here.
*/
if (block_size >= MAXPHYS || block_size == 0) {
xpt_print(periph->path,
"unsupportable block size %ju\n",
(uintmax_t) block_size);
announce_buf[0] = '\0';
cam_periph_invalidate(periph);
} else {
dasetgeom(periph, block_size, maxsector);
dp = &softc->params;
snprintf(announce_buf, sizeof(announce_buf),
"%juMB (%ju %u byte sectors: %dH %dS/T "
"%dC)", (uintmax_t)
(((uintmax_t)dp->secsize *
dp->sectors) / (1024*1024)),
(uintmax_t)dp->sectors,
dp->secsize, dp->heads,
dp->secs_per_track, dp->cylinders);
}
} else {
int error;
announce_buf[0] = '\0';
/*
* Retry any UNIT ATTENTION type errors. They
* are expected at boot.
*/
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
error = daerror(done_ccb, CAM_RETRY_SELTO,
SF_RETRY_UA|SF_NO_PRINT);
if (error == ERESTART) {
/*
* A retry was scheuled, so
* just return.
*/
return;
} else if (error != 0) {
struct scsi_sense_data *sense;
int asc, ascq;
int sense_key, error_code;
int have_sense;
cam_status status;
struct ccb_getdev cgd;
/* Don't wedge this device's queue */
status = done_ccb->ccb_h.status;
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
if ((status & CAM_DEV_QFRZN) != 0)
cam_release_devq(done_ccb->ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
xpt_setup_ccb(&cgd.ccb_h,
done_ccb->ccb_h.path,
/* priority */ 1);
cgd.ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action((union ccb *)&cgd);
if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
|| ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
|| ((status & CAM_AUTOSNS_VALID) == 0))
have_sense = FALSE;
else
have_sense = TRUE;
if (have_sense) {
sense = &csio->sense_data;
scsi_extract_sense(sense, &error_code,
&sense_key,
&asc, &ascq);
}
/*
Add a number of interrelated CAM feature enhancements and bug fixes. NOTE: These changes will require recompilation of any userland applications, like cdrecord, xmcd, etc., that use the CAM passthrough interface. A make world is recommended. camcontrol.[c8]: - We now support two new commands, "tags" and "negotiate". - The tags commands allows users to view the number of tagged openings for a device as well as a number of other related parameters, and it allows users to set tagged openings for a device. - The negotiate command allows users to enable and disable disconnection and tagged queueing, set sync rates, offsets and bus width. Note that not all of those features are available for all controllers. Only the adv, ahc, and ncr drivers fully support all of the features at this point. Some cards do not allow the setting of sync rates, offsets and the like, and some of the drivers don't have any facilities to do so. Some drivers, like the adw driver, only support enabling or disabling sync negotiation, but do not support setting sync rates. - new description in the camcontrol man page of how to format a disk - cleanup of the camcontrol inquiry command - add support in the 'devlist' command for skipping unconfigured devices if -v was not specified on the command line. - make use of the new base_transfer_speed in the path inquiry CCB. - fix CCB bzero cases cam_xpt.c, cam_sim.[ch], cam_ccb.h: - new flags on many CCB function codes to designate whether they're non-immediate, use a user-supplied CCB, and can only be passed from userland programs via the xpt device. Use these flags in the transport layer and pass driver to categorize CCBs. - new flag in the transport layer device matching code for device nodes that indicates whether a device is unconfigured - bump the CAM version from 0x10 to 0x11 - Change the CAM ioctls to use the version as their group code, so we can force users to recompile code even when the CCB size doesn't change. - add + fill in a new value in the path inquiry CCB, base_transfer_speed. Remove a corresponding field from the cam_sim structure, and add code to every SIM to set this field to the proper value. - Fix the set transfer settings code in the transport layer. scsi_cd.c: - make some variables volatile instead of just casting them in various places - fix a race condition in the changer code - attach unless we get a "logical unit not supported" error. This should fix all of the cases where people have devices that return weird errors when they don't have media in the drive. scsi_da.c: - attach unless we get a "logical unit not supported" error scsi_pass.c: - for immediate CCBs, just malloc a CCB to send the user request in. This gets rid of the 'held' count problem in camcontrol tags. scsi_pass.h: - change the CAM ioctls to use the CAM version as their group code. adv driver: - Allow changing the sync rate and offset separately. adw driver - Allow changing the sync rate and offset separately. aha driver: - Don't return CAM_REQ_CMP for SET_TRAN_SETTINGS CCBs. ahc driver: - Allow setting offset and sync rate separately bt driver: - Don't return CAM_REQ_CMP for SET_TRAN_SETTINGS CCBs. NCR driver: - Fix the ultra/ultra 2 negotiation bug - allow setting both the sync rate and offset separately Other HBA drivers: - Put code in to set the base_transfer_speed field for XPT_GET_TRAN_SETTINGS CCBs. Reviewed by: gibbs, mjacob (isp), imp (aha)
1999-05-06 20:16:39 +00:00
* Attach to anything that claims to be a
* direct access or optical disk device,
* as long as it doesn't return a "Logical
* unit not supported" (0x25) error.
*/
Add a number of interrelated CAM feature enhancements and bug fixes. NOTE: These changes will require recompilation of any userland applications, like cdrecord, xmcd, etc., that use the CAM passthrough interface. A make world is recommended. camcontrol.[c8]: - We now support two new commands, "tags" and "negotiate". - The tags commands allows users to view the number of tagged openings for a device as well as a number of other related parameters, and it allows users to set tagged openings for a device. - The negotiate command allows users to enable and disable disconnection and tagged queueing, set sync rates, offsets and bus width. Note that not all of those features are available for all controllers. Only the adv, ahc, and ncr drivers fully support all of the features at this point. Some cards do not allow the setting of sync rates, offsets and the like, and some of the drivers don't have any facilities to do so. Some drivers, like the adw driver, only support enabling or disabling sync negotiation, but do not support setting sync rates. - new description in the camcontrol man page of how to format a disk - cleanup of the camcontrol inquiry command - add support in the 'devlist' command for skipping unconfigured devices if -v was not specified on the command line. - make use of the new base_transfer_speed in the path inquiry CCB. - fix CCB bzero cases cam_xpt.c, cam_sim.[ch], cam_ccb.h: - new flags on many CCB function codes to designate whether they're non-immediate, use a user-supplied CCB, and can only be passed from userland programs via the xpt device. Use these flags in the transport layer and pass driver to categorize CCBs. - new flag in the transport layer device matching code for device nodes that indicates whether a device is unconfigured - bump the CAM version from 0x10 to 0x11 - Change the CAM ioctls to use the version as their group code, so we can force users to recompile code even when the CCB size doesn't change. - add + fill in a new value in the path inquiry CCB, base_transfer_speed. Remove a corresponding field from the cam_sim structure, and add code to every SIM to set this field to the proper value. - Fix the set transfer settings code in the transport layer. scsi_cd.c: - make some variables volatile instead of just casting them in various places - fix a race condition in the changer code - attach unless we get a "logical unit not supported" error. This should fix all of the cases where people have devices that return weird errors when they don't have media in the drive. scsi_da.c: - attach unless we get a "logical unit not supported" error scsi_pass.c: - for immediate CCBs, just malloc a CCB to send the user request in. This gets rid of the 'held' count problem in camcontrol tags. scsi_pass.h: - change the CAM ioctls to use the CAM version as their group code. adv driver: - Allow changing the sync rate and offset separately. adw driver - Allow changing the sync rate and offset separately. aha driver: - Don't return CAM_REQ_CMP for SET_TRAN_SETTINGS CCBs. ahc driver: - Allow setting offset and sync rate separately bt driver: - Don't return CAM_REQ_CMP for SET_TRAN_SETTINGS CCBs. NCR driver: - Fix the ultra/ultra 2 negotiation bug - allow setting both the sync rate and offset separately Other HBA drivers: - Put code in to set the base_transfer_speed field for XPT_GET_TRAN_SETTINGS CCBs. Reviewed by: gibbs, mjacob (isp), imp (aha)
1999-05-06 20:16:39 +00:00
if ((have_sense) && (asc != 0x25)
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
&& (error_code == SSD_CURRENT_ERROR)) {
const char *sense_key_desc;
const char *asc_desc;
scsi_sense_desc(sense_key, asc, ascq,
&cgd.inq_data,
&sense_key_desc,
&asc_desc);
snprintf(announce_buf,
sizeof(announce_buf),
"Attempt to query device "
"size failed: %s, %s",
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
sense_key_desc,
asc_desc);
} else {
Some fixes for the CD and DA drivers from bde. (and some of my own as well) Among them: [ cd driver ] 1. Old labeling code was still there. 2. Error handling for dsopen() was broken (no test for the `error' returned by dsopen(); bogus test of an `error' that is known to be 0). 3. cdopen() closed the physical device after certain errors although there may still be open partitions on it. 4. cdclose() closed the physical device although there may still be open partitions on it. 5. Some printf format fixes was incomplete or missing. 6. cdioctl() truncated unit numbers mod 256. 7. cdioctl() was missing locking. [ da driver ] 1. daclose() closed the physical device although there may still be open partitions on it. This was fixed many years ago in sd.c rev.1.57. 2. A minor optimization (the dk_slices != NULL test) in sdopen() became uglier in daopen(). It is not worth doing. da only regressed compared with od and my version of sd, since I never committed the change to sd. daopen() should probably do less if some partition is already open. This is not addressed by the diffs. [ ... ] 5. "opt_hw_wdog.h" was not included, so the HW_WDOG code was unreachable. - Added a getdev CCB call in the cdopen() and daopen() calls so that the vendor name and device name are available for the disklabel. (suggested by bde) - Removed vestigal devfs support in both drivers, since we can't properly work with devfs yet. (ask bde for details on this) - Cleaned up the probe code in both drivers in the failure cases. There were a number of things wrong here. The peripheral driver instances weren't getting properly cleaned up. Sometimes the wrong probe message would get printed out (with the failure message appended), so it wasn't very clear that we failed to attach. SCSI sense information was printed, even when the error in question wasn't a SCSI error. I put similar fixes into the changer driver in revision 1.2 of scsi_ch.c. Reviewed by: gibbs Submitted by: bde (partially)
1998-10-07 02:57:57 +00:00
if (have_sense)
scsi_sense_print(
&done_ccb->csio);
else {
xpt_print(periph->path,
"got CAM status %#x\n",
done_ccb->ccb_h.status);
Some fixes for the CD and DA drivers from bde. (and some of my own as well) Among them: [ cd driver ] 1. Old labeling code was still there. 2. Error handling for dsopen() was broken (no test for the `error' returned by dsopen(); bogus test of an `error' that is known to be 0). 3. cdopen() closed the physical device after certain errors although there may still be open partitions on it. 4. cdclose() closed the physical device although there may still be open partitions on it. 5. Some printf format fixes was incomplete or missing. 6. cdioctl() truncated unit numbers mod 256. 7. cdioctl() was missing locking. [ da driver ] 1. daclose() closed the physical device although there may still be open partitions on it. This was fixed many years ago in sd.c rev.1.57. 2. A minor optimization (the dk_slices != NULL test) in sdopen() became uglier in daopen(). It is not worth doing. da only regressed compared with od and my version of sd, since I never committed the change to sd. daopen() should probably do less if some partition is already open. This is not addressed by the diffs. [ ... ] 5. "opt_hw_wdog.h" was not included, so the HW_WDOG code was unreachable. - Added a getdev CCB call in the cdopen() and daopen() calls so that the vendor name and device name are available for the disklabel. (suggested by bde) - Removed vestigal devfs support in both drivers, since we can't properly work with devfs yet. (ask bde for details on this) - Cleaned up the probe code in both drivers in the failure cases. There were a number of things wrong here. The peripheral driver instances weren't getting properly cleaned up. Sometimes the wrong probe message would get printed out (with the failure message appended), so it wasn't very clear that we failed to attach. SCSI sense information was printed, even when the error in question wasn't a SCSI error. I put similar fixes into the changer driver in revision 1.2 of scsi_ch.c. Reviewed by: gibbs Submitted by: bde (partially)
1998-10-07 02:57:57 +00:00
}
xpt_print(periph->path, "fatal error, "
"failed to attach to device\n");
/*
* Free up resources.
*/
cam_periph_invalidate(periph);
}
}
}
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
free(csio->data_ptr, M_TEMP);
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
if (announce_buf[0] != '\0') {
xpt_announce_periph(periph, announce_buf);
Move dynamic sysctl(8) variable creation for the cd(4) and da(4) drivers out of cdregister() and daregister(), which are run from interrupt context. The sysctl code does blocking mallocs (M_WAITOK), which causes problems if malloc(9) actually needs to sleep. The eventual fix for this issue will involve moving the CAM probe process inside a kernel thread. For now, though, I have fixed the issue by moving dynamic sysctl variable creation for these two drivers to a task queue running in a kernel thread. The existing task queues (taskqueue_swi and taskqueue_swi_giant) run in software interrupt handlers, which wouldn't fix the problem at hand. So I have created a new task queue, taskqueue_thread, that runs inside a kernel thread. (It also runs outside of Giant -- clients must explicitly acquire and release Giant in their taskqueue functions.) scsi_cd.c: Remove sysctl variable creation code from cdregister(), and move it to a new function, cdsysctlinit(). Queue cdsysctlinit() to the taskqueue_thread taskqueue once we have fully registered the cd(4) driver instance. scsi_da.c: Remove sysctl variable creation code from daregister(), and move it to move it to a new function, dasysctlinit(). Queue dasysctlinit() to the taskqueue_thread taskqueue once we have fully registered the da(4) instance. taskqueue.h: Declare the new taskqueue_thread taskqueue, update some comments. subr_taskqueue.c: Create the new kernel thread taskqueue. This taskqueue runs outside of Giant, so any functions queued to it would need to explicitly acquire/release Giant if they need it. cd.4: Update the cd(4) man page to talk about the minimum command size sysctl/loader tunable. Also note that the changer variables are available as loader tunables as well. da.4: Update the da(4) man page to cover the retry_count, default_timeout and minimum_cmd_size sysctl variables/loader tunables. Remove references to /dev/r???, they aren't used any longer. cd.9: Update the cd(9) man page to describe the CD_Q_10_BYTE_ONLY quirk. taskqueue.9: Update the taskqueue(9) man page to describe the new thread task queue, and the taskqueue_swi_giant queue. MFC after: 3 days
2003-09-03 04:46:28 +00:00
/*
* Create our sysctl variables, now that we know
* we have successfully attached.
*/
taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
}
Rewrite of the CAM error recovery code. Some of the major changes include: - The SCSI error handling portion of cam_periph_error() has been broken out into a number of subfunctions to better modularize the code that handles the hierarchy of SCSI errors. As a result, the code is now much easier to read. - String handling and error printing has been significantly revamped. We now use sbufs to do string formatting instead of using printfs (for the kernel) and snprintf/strncat (for userland) as before. There is a new catchall error printing routine, cam_error_print() and its string-based counterpart, cam_error_string() that allow the kernel and userland applications to pass in a CCB and have errors printed out properly, whether or not they're SCSI errors. Among other things, this helped eliminate a fair amount of duplicate code in camcontrol. We now print out more information than before, including the CAM status and SCSI status and the error recovery action taken to remedy the problem. - sbufs are now available in userland, via libsbuf. This change was necessary since most of the error printing code is shared between libcam and the kernel. - A new transfer settings interface is included in this checkin. This code is #ifdef'ed out, and is primarily intended to aid discussion with HBA driver authors on the final form the interface should take. There is example code in the ahc(4) driver that implements the HBA driver side of the new interface. The new transfer settings code won't be enabled until we're ready to switch all HBA drivers over to the new interface. src/Makefile.inc1, lib/Makefile: Add libsbuf. It must be built before libcam, since libcam uses sbuf routines. libcam/Makefile: libcam now depends on libsbuf. libsbuf/Makefile: Add a makefile for libsbuf. This pulls in the sbuf sources from sys/kern. bsd.libnames.mk: Add LIBSBUF. camcontrol/Makefile: Add -lsbuf. Since camcontrol is statically linked, we can't depend on the dynamic linker to pull in libsbuf. camcontrol.c: Use cam_error_print() instead of checking for CAM_SCSI_STATUS_ERROR on every failed CCB. sbuf.9: Change the prototypes for sbuf_cat() and sbuf_cpy() so that the source string is now a const char *. This is more in line wth the standard system string functions, and helps eliminate warnings when dealing with a const source buffer. Fix a typo. cam.c: Add description strings for the various CAM error status values, as well as routines to look up those strings. Add new cam_error_string() and cam_error_print() routines for userland and the kernel. cam.h: Add a new CAM flag, CAM_RETRY_SELTO. Add enumerated types for the various options available with cam_error_print() and cam_error_string(). cam_ccb.h: Add new transfer negotiation structures/types. Change inq_len in the ccb_getdev structure to be "reserved". This field has never been filled in, and will be removed when we next bump the CAM version. cam_debug.h: Fix typo. cam_periph.c: Modularize cam_periph_error(). The SCSI error handling part of cam_periph_error() is now in camperiphscsistatuserror() and camperiphscsisenseerror(). In cam_periph_lock(), increase the reference count on the periph while we wait for our lock attempt to succeed so that the periph won't go away while we're sleeping. cam_xpt.c: Add new transfer negotiation code. (ifdefed out) Add a new function, xpt_path_string(). This is a string/sbuf analog to xpt_print_path(). scsi_all.c: Revamp string handing and error printing code. We now use sbufs for much of the string formatting code. More of that code is shared between userland the kernel. scsi_all.h: Get rid of SS_TURSTART, it wasn't terribly useful in the first place. Add a new error action, SS_REQSENSE. (Send a request sense and then retry the command.) This is useful when the controller hasn't performed autosense for some reason. Change the default actions around a bit. scsi_cd.c, scsi_da.c, scsi_pt.c, scsi_ses.c: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Selection timeouts shouldn't be covered by a sense flag. scsi_pass.[ch]: SF_RETRY_SELTO -> CAM_RETRY_SELTO. Get rid of the last vestiges of a read/write interface. libkern/bsearch.c, sys/libkern.h, conf/files: Add bsearch.c, which is needed for some of the new table lookup routines. aic7xxx_freebsd.c: Define AHC_NEW_TRAN_SETTINGS if CAM_NEW_TRAN_CODE is defined. sbuf.h, subr_sbuf.c: Add the appropriate #ifdefs so sbufs can compile and run in userland. Change sbuf_printf() to use vsnprintf() instead of kvprintf(), which is only available in the kernel. Change the source string for sbuf_cpy() and sbuf_cat() to be a const char *. Add __BEGIN_DECLS and __END_DECLS around function prototypes since they're now exported to userland. kdump/mkioctls: Include stdio.h before cam.h since cam.h now includes a function with a FILE * argument. Submitted by: gibbs (mostly) Reviewed by: jdp, marcel (libsbuf makefile changes) Reviewed by: des (sbuf changes) Reviewed by: ken
2001-03-27 05:45:52 +00:00
softc->state = DA_STATE_NORMAL;
/*
* Since our peripheral may be invalidated by an error
* above or an external event, we must release our CCB
* before releasing the probe lock on the peripheral.
* The peripheral will only go away once the last lock
* is removed, and we need it around for the CCB release
* operation.
*/
xpt_release_ccb(done_ccb);
Some fixes for the CD and DA drivers from bde. (and some of my own as well) Among them: [ cd driver ] 1. Old labeling code was still there. 2. Error handling for dsopen() was broken (no test for the `error' returned by dsopen(); bogus test of an `error' that is known to be 0). 3. cdopen() closed the physical device after certain errors although there may still be open partitions on it. 4. cdclose() closed the physical device although there may still be open partitions on it. 5. Some printf format fixes was incomplete or missing. 6. cdioctl() truncated unit numbers mod 256. 7. cdioctl() was missing locking. [ da driver ] 1. daclose() closed the physical device although there may still be open partitions on it. This was fixed many years ago in sd.c rev.1.57. 2. A minor optimization (the dk_slices != NULL test) in sdopen() became uglier in daopen(). It is not worth doing. da only regressed compared with od and my version of sd, since I never committed the change to sd. daopen() should probably do less if some partition is already open. This is not addressed by the diffs. [ ... ] 5. "opt_hw_wdog.h" was not included, so the HW_WDOG code was unreachable. - Added a getdev CCB call in the cdopen() and daopen() calls so that the vendor name and device name are available for the disklabel. (suggested by bde) - Removed vestigal devfs support in both drivers, since we can't properly work with devfs yet. (ask bde for details on this) - Cleaned up the probe code in both drivers in the failure cases. There were a number of things wrong here. The peripheral driver instances weren't getting properly cleaned up. Sometimes the wrong probe message would get printed out (with the failure message appended), so it wasn't very clear that we failed to attach. SCSI sense information was printed, even when the error in question wasn't a SCSI error. I put similar fixes into the changer driver in revision 1.2 of scsi_ch.c. Reviewed by: gibbs Submitted by: bde (partially)
1998-10-07 02:57:57 +00:00
cam_periph_unlock(periph);
return;
}
case DA_CCB_WAITING:
{
/* Caller will release the CCB */
wakeup(&done_ccb->ccb_h.cbfcnp);
return;
}
case DA_CCB_DUMP:
/* No-op. We're polling */
return;
default:
break;
}
xpt_release_ccb(done_ccb);
}
static int
daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
{
struct da_softc *softc;
struct cam_periph *periph;
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
int error;
periph = xpt_path_periph(ccb->ccb_h.path);
softc = (struct da_softc *)periph->softc;
/*
* Automatically detect devices that do not support
* READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
*/
error = 0;
Fix ATAPI/USB/Firewire CDROM drive handling in cd(4) and hopefully fix a number of related problems along the way. - Automatically detect CDROM drives that can't handle 6 byte mode sense and mode select, and adjust our command size accordingly. We have to handle this in the cd(4) driver (where the buffers are allocated), since the parameter list length is different for the 6 and 10 byte mode sense commands. - Remove MODE_SENSE and MODE_SELECT translation removed in ATAPICAM and in the umass(4) driver, since there's no way for that to work properly. - Add a quirk entry for CDROM drives that just hang when they get a 6 byte mode sense or mode select. The reason for the quirk must be documented in a PR, and all quirks must be approved by ken@FreeBSD.org. This is to make sure that we fully understand why each quirk is needed. Once the CAM_NEW_TRAN_CODE is finished, we should be able to remove any such quirks, since we'll know what protocol the drive speaks (SCSI, ATAPI, etc.) and therefore whether we should use 6 or 10 byte mode sense/select commands. - Change the way the da(4) handles the no_6_byte sysctl. There is now a per-drive sysctl to set the minimum command size for that particular disk. (Since you could have multiple disks with multiple requirements in one system.) - Loader tunable support for all the sysctls in the da(4) and cd(4) drivers. - Add a CDIOCCLOSE ioctl for cd(4) (bde pointed this out a long time ago). - Add a media validation routine (cdcheckmedia()) to the cd(4) driver, to fix some problems bde pointed out a long time ago. We now allow open() to succeed no matter what, but if we don't detect valid media, the user can only issue CDIOCCLOSE or CDIOCEJECT ioctls. - The media validation routine also reads the table of contents off the drive. We use the table of contents to implement the CDIOCPLAYTRACKS ioctl using the PLAY AUDIO MSF command. The PLAY AUDIO TRACK INDEX command that we previously used was deprecated after SCSI-2. It works in every SCSI CDROM I've tried, but doesn't seem to work on ATAPI CDROM drives. We still use the play audio track index command if we don't have a valid TOC, but I suppose it'll fail anyway in that case. - Add _len() versions of scsi_mode_sense() and scsi_mode_select() so that we can specify the minimum command length. - Fix a couple of formatting problems in the sense printing code. MFC after: 4 weeks
2003-02-21 06:19:38 +00:00
if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
error = cmd6workaround(ccb);
} else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
CAM_SCSI_STATUS_ERROR)
&& (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
&& (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
&& ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
&& ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
int sense_key, error_code, asc, ascq;
scsi_extract_sense(&ccb->csio.sense_data,
&error_code, &sense_key, &asc, &ascq);
if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
error = cmd6workaround(ccb);
}
if (error == ERESTART)
return (ERESTART);
/*
* XXX
* Until we have a better way of doing pack validation,
* don't treat UAs as errors.
*/
sense_flags |= SF_RETRY_UA;
return(cam_periph_error(ccb, cam_flags, sense_flags,
&softc->saved_ccb));
}
static void
daprevent(struct cam_periph *periph, int action)
{
struct da_softc *softc;
union ccb *ccb;
int error;
softc = (struct da_softc *)periph->softc;
if (((action == PR_ALLOW)
&& (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
|| ((action == PR_PREVENT)
&& (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
return;
}
ccb = cam_periph_getccb(periph, /*priority*/1);
scsi_prevent(&ccb->csio,
/*retries*/1,
/*cbcfp*/dadone,
MSG_SIMPLE_Q_TAG,
action,
SSD_FULL_SIZE,
5000);
error = cam_periph_runccb(ccb, /*error_routine*/NULL, CAM_RETRY_SELTO,
SF_RETRY_UA, softc->disk->d_devstat);
if (error == 0) {
if (action == PR_ALLOW)
softc->flags &= ~DA_FLAG_PACK_LOCKED;
else
softc->flags |= DA_FLAG_PACK_LOCKED;
}
xpt_release_ccb(ccb);
}
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
static int
dagetcapacity(struct cam_periph *periph)
{
struct da_softc *softc;
union ccb *ccb;
struct scsi_read_capacity_data *rcap;
struct scsi_read_capacity_data_long *rcaplong;
uint32_t block_len;
uint64_t maxsector;
int error;
u_int32_t sense_flags;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
softc = (struct da_softc *)periph->softc;
block_len = 0;
maxsector = 0;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
error = 0;
sense_flags = SF_RETRY_UA;
if (softc->flags & DA_FLAG_PACK_REMOVABLE)
sense_flags |= SF_NO_PRINT;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
/* Do a read capacity */
rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcaplong),
M_TEMP,
M_WAITOK);
ccb = cam_periph_getccb(periph, /*priority*/1);
scsi_read_capacity(&ccb->csio,
/*retries*/4,
/*cbfncp*/dadone,
MSG_SIMPLE_Q_TAG,
rcap,
SSD_FULL_SIZE,
/*timeout*/60000);
ccb->ccb_h.ccb_bp = NULL;
error = cam_periph_runccb(ccb, daerror,
/*cam_flags*/CAM_RETRY_SELTO,
sense_flags,
softc->disk->d_devstat);
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(ccb->ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
if (error == 0) {
block_len = scsi_4btoul(rcap->length);
maxsector = scsi_4btoul(rcap->addr);
if (maxsector != 0xffffffff)
goto done;
} else
goto done;
rcaplong = (struct scsi_read_capacity_data_long *)rcap;
scsi_read_capacity_16(&ccb->csio,
/*retries*/ 4,
/*cbfcnp*/ dadone,
/*tag_action*/ MSG_SIMPLE_Q_TAG,
/*lba*/ 0,
/*reladr*/ 0,
/*pmi*/ 0,
rcaplong,
/*sense_len*/ SSD_FULL_SIZE,
/*timeout*/ 60000);
ccb->ccb_h.ccb_bp = NULL;
error = cam_periph_runccb(ccb, daerror,
/*cam_flags*/CAM_RETRY_SELTO,
sense_flags,
softc->disk->d_devstat);
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(ccb->ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
if (error == 0) {
block_len = scsi_4btoul(rcaplong->length);
maxsector = scsi_8btou64(rcaplong->addr);
}
done:
if (error == 0)
dasetgeom(periph, block_len, maxsector);
xpt_release_ccb(ccb);
free(rcap, M_TEMP);
return (error);
}
static void
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector)
{
struct ccb_calc_geometry ccg;
struct da_softc *softc;
struct disk_params *dp;
softc = (struct da_softc *)periph->softc;
dp = &softc->params;
Add support to CAM for devices with more than 2^32 blocks. (2TB if you're using 512 byte blocks). cam_ccb.h: Bump up volume_size and cylinders in ccb_calc_geometry to 64 bits and 32 bits respectively, so we can hold larger device sizes. cylinders would overflow at about 500GB. Bump CAM_VERSION for this change. Note that this will require a recompile of all applications that talk to the pass(4) driver. scsi_all.c: Add descriptions for READ/WRITE(16), update READ/WRITE(12) descriptions, add descriptions for SERVICE ACTION IN/OUT. Add a new function, scsi_read_capacity_16(), that issues the read capacity service action. (Necessary for arrays larger than 2^32 sectors.) Update scsi_read_write() to use a 64 bit LBA and issue READ(16) or WRITE(16) if necessary. NOTE the API change. This should be largely transparnet to most userland applications at compile time, but will break binary compatibility. The CAM_VERSION bump, above, also serves the purpose of forcing a recompile for any applications that talk to CAM. scsi_all.h: Add 16 byte READ/WRITE structures, structures for 16 byte READ CAPACITY/SERVICE ACTION IN. Add scsi_u64to8b() and scsi_8btou64. scsi_da.c: The da(4) driver probe now has two stages for devices larger than 2TB. If a standard READ CAPACITY(10) returns 0xffffffff, we issue the 16 byte version of read capacity to determine the true array capacity. We also do the same thing in daopen() -- use the 16 byte read capacity if the device is large enough. The sysctl/loader code has also been updated to accept 16 bytes as a minimum command size.
2003-04-30 00:35:22 +00:00
dp->secsize = block_len;
dp->sectors = maxsector + 1;
/*
* Have the controller provide us with a geometry
* for this disk. The only time the geometry
* matters is when we boot and the controller
* is the only one knowledgeable enough to come
* up with something that will make this a bootable
* device.
*/
xpt_setup_ccb(&ccg.ccb_h, periph->path, /*priority*/1);
ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
ccg.block_size = dp->secsize;
ccg.volume_size = dp->sectors;
ccg.heads = 0;
ccg.secs_per_track = 0;
ccg.cylinders = 0;
xpt_action((union ccb*)&ccg);
if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
/*
* We don't know what went wrong here- but just pick
* a geometry so we don't have nasty things like divide
* by zero.
*/
dp->heads = 255;
dp->secs_per_track = 255;
dp->cylinders = dp->sectors / (255 * 255);
if (dp->cylinders == 0) {
dp->cylinders = 1;
}
} else {
dp->heads = ccg.heads;
dp->secs_per_track = ccg.secs_per_track;
dp->cylinders = ccg.cylinders;
}
}
static void
dasendorderedtag(void *arg)
{
struct da_softc *softc;
int s;
if (da_send_ordered) {
for (softc = SLIST_FIRST(&softc_list);
softc != NULL;
softc = SLIST_NEXT(softc, links)) {
s = splsoftcam();
if ((softc->ordered_tag_count == 0)
&& ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
softc->flags |= DA_FLAG_NEED_OTAG;
}
if (softc->outstanding_cmds > 0)
softc->flags &= ~DA_FLAG_WENT_IDLE;
softc->ordered_tag_count = 0;
splx(s);
}
/* Queue us up again */
timeout(dasendorderedtag, NULL,
(da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL);
}
}
/*
* Step through all DA peripheral drivers, and if the device is still open,
* sync the disk cache to physical media.
*/
static void
dashutdown(void * arg, int howto)
{
struct cam_periph *periph;
struct da_softc *softc;
TAILQ_FOREACH(periph, &dadriver.units, unit_links) {
union ccb ccb;
softc = (struct da_softc *)periph->softc;
/*
* We only sync the cache if the drive is still open, and
* if the drive is capable of it..
*/
if (((softc->flags & DA_FLAG_OPEN) == 0)
|| (softc->quirks & DA_Q_NO_SYNC_CACHE))
continue;
xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
ccb.ccb_h.ccb_state = DA_CCB_DUMP;
scsi_synchronize_cache(&ccb.csio,
/*retries*/1,
/*cbfcnp*/dadone,
MSG_SIMPLE_Q_TAG,
/*begin_lba*/0, /* whole disk */
/*lb_count*/0,
SSD_FULL_SIZE,
60 * 60 * 1000);
xpt_polled_action(&ccb);
if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
CAM_SCSI_STATUS_ERROR)
&& (ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND)){
int error_code, sense_key, asc, ascq;
scsi_extract_sense(&ccb.csio.sense_data,
&error_code, &sense_key,
&asc, &ascq);
if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
scsi_sense_print(&ccb.csio);
} else {
xpt_print(periph->path, "Synchronize "
"cache failed, status == 0x%x, scsi status "
"== 0x%x\n", ccb.ccb_h.status,
ccb.csio.scsi_status);
}
}
if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(ccb.ccb_h.path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
}
}
#else /* !_KERNEL */
/*
* XXX This is only left out of the kernel build to silence warnings. If,
* for some reason this function is used in the kernel, the ifdefs should
* be moved so it is included both in the kernel and userland.
*/
void
scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
u_int32_t timeout)
{
struct scsi_format_unit *scsi_cmd;
scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
scsi_cmd->opcode = FORMAT_UNIT;
scsi_cmd->byte2 = byte2;
scsi_ulto2b(ileave, scsi_cmd->interleave);
cam_fill_csio(csio,
retries,
cbfcnp,
/*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
tag_action,
data_ptr,
dxfer_len,
sense_len,
sizeof(*scsi_cmd),
timeout);
}
#endif /* _KERNEL */