2005-01-05 22:34:37 +00:00
|
|
|
/*-
|
1998-09-15 06:36:34 +00:00
|
|
|
* 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$");
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
#include <sys/param.h>
|
2000-05-21 23:57:52 +00:00
|
|
|
|
|
|
|
#ifdef _KERNEL
|
1998-09-15 06:36:34 +00:00
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/kernel.h>
|
2000-05-05 09:59:14 +00:00
|
|
|
#include <sys/bio.h>
|
2001-07-09 19:18:00 +00:00
|
|
|
#include <sys/sysctl.h>
|
2003-09-03 12:31:03 +00:00
|
|
|
#include <sys/taskqueue.h>
|
2000-05-21 23:57:52 +00:00
|
|
|
#endif /* _KERNEL */
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
#include <sys/devicestat.h>
|
1999-10-01 09:34:10 +00:00
|
|
|
#include <sys/conf.h>
|
1999-08-21 06:24:40 +00:00
|
|
|
#include <sys/eventhandler.h>
|
1998-09-15 06:36:34 +00:00
|
|
|
#include <sys/malloc.h>
|
1999-08-09 10:35:05 +00:00
|
|
|
#include <sys/cons.h>
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1998-10-07 02:57:57 +00:00
|
|
|
#include <machine/md_var.h>
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
#include <vm/vm.h>
|
|
|
|
#include <vm/pmap.h>
|
|
|
|
|
2003-04-01 15:06:26 +00:00
|
|
|
#include <geom/geom_disk.h>
|
|
|
|
|
2000-05-21 23:57:52 +00:00
|
|
|
#ifndef _KERNEL
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#endif /* _KERNEL */
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
#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>
|
|
|
|
|
2000-05-21 23:57:52 +00:00
|
|
|
#ifndef _KERNEL
|
|
|
|
#include <cam/scsi/scsi_da.h>
|
|
|
|
#endif /* !_KERNEL */
|
|
|
|
|
|
|
|
#ifdef _KERNEL
|
1998-09-15 06:36:34 +00:00
|
|
|
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,
|
1998-09-15 06:36:34 +00:00
|
|
|
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,
|
2003-10-08 07:12:30 +00:00
|
|
|
DA_FLAG_OPEN = 0x100,
|
|
|
|
DA_FLAG_SCTX_INIT = 0x200
|
1998-09-15 06:36:34 +00:00
|
|
|
} da_flags;
|
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
typedef enum {
|
|
|
|
DA_Q_NONE = 0x00,
|
1998-12-02 17:35:28 +00:00
|
|
|
DA_Q_NO_SYNC_CACHE = 0x01,
|
2003-08-22 16:35:53 +00:00
|
|
|
DA_Q_NO_6_BYTE = 0x02,
|
|
|
|
DA_Q_NO_PREVENT = 0x04
|
1998-10-08 05:46:38 +00:00
|
|
|
} da_quirks;
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
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,
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
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 */
|
1998-09-15 06:36:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct da_softc {
|
2000-04-15 05:54:02 +00:00
|
|
|
struct bio_queue_head bio_queue;
|
2000-05-26 02:09:24 +00:00
|
|
|
SLIST_ENTRY(da_softc) links;
|
|
|
|
LIST_HEAD(, ccb_hdr) pending_ccbs;
|
1998-09-15 06:36:34 +00:00
|
|
|
da_state state;
|
|
|
|
da_flags flags;
|
1998-10-08 05:46:38 +00:00
|
|
|
da_quirks quirks;
|
1998-12-02 17:35:28 +00:00
|
|
|
int minimum_cmd_size;
|
1998-09-15 06:36:34 +00:00
|
|
|
int ordered_tag_count;
|
2003-03-15 11:00:56 +00:00
|
|
|
int outstanding_cmds;
|
1998-09-15 06:36:34 +00:00
|
|
|
struct disk_params params;
|
2004-02-18 21:36:53 +00:00
|
|
|
struct disk *disk;
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
};
|
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
struct da_quirk_entry {
|
|
|
|
struct scsi_inquiry_pattern inq_pat;
|
|
|
|
da_quirks quirks;
|
|
|
|
};
|
|
|
|
|
2000-08-29 22:09:23 +00:00
|
|
|
static const char quantum[] = "QUANTUM";
|
|
|
|
static const char microp[] = "MICROP";
|
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
static struct da_quirk_entry da_quirk_table[] =
|
|
|
|
{
|
2003-08-25 18:14:43 +00:00
|
|
|
/* SPI, FC devices */
|
2001-11-17 14:46:22 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
},
|
1998-10-08 05:46:38 +00:00
|
|
|
{
|
1998-10-12 17:16:47 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
1998-10-08 05:46:38 +00:00
|
|
|
*/
|
2000-08-29 22:09:23 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
|
1998-10-12 17:16:47 +00:00
|
|
|
/*quirks*/ DA_Q_NO_SYNC_CACHE
|
1998-10-13 23:34:54 +00:00
|
|
|
},
|
1999-01-05 20:43:41 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* This drive doesn't like the synchronize cache command
|
|
|
|
* either. Reported by: Hellmuth Michaelis (hm@kts.org)
|
|
|
|
* (PR 8882).
|
|
|
|
*/
|
2000-08-29 22:09:23 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
|
1999-01-05 20:43:41 +00:00
|
|
|
/*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
1998-10-13 23:34:54 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
1998-12-02 17:35:28 +00:00
|
|
|
},
|
2000-08-29 22:09:23 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Doesn't like the synchronize cache command.
|
2005-04-14 04:46:46 +00:00
|
|
|
* Reported by: Blaz Zupan <blaz@gold.amis.net>
|
2000-08-29 22:09:23 +00:00
|
|
|
*/
|
|
|
|
{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
|
|
|
|
},
|
2005-04-14 04:05:00 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Doesn't like the synchronize cache command.
|
2005-04-14 04:46:46 +00:00
|
|
|
* Reported by: walter@pelissero.de
|
2005-04-14 04:05:00 +00:00
|
|
|
*/
|
|
|
|
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
|
|
|
|
/*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
1998-12-02 17:35:28 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
*/
|
2000-08-29 22:09:23 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
|
1998-12-02 17:35:28 +00:00
|
|
|
/*quirks*/ DA_Q_NO_6_BYTE
|
|
|
|
},
|
|
|
|
{
|
2003-08-22 16:35:53 +00:00
|
|
|
/* See above. */
|
2000-08-29 22:09:23 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
|
1998-12-02 17:35:28 +00:00
|
|
|
/*quirks*/ DA_Q_NO_6_BYTE
|
2000-03-15 22:44:03 +00:00
|
|
|
},
|
2005-04-14 04:12:45 +00:00
|
|
|
{
|
2005-04-14 04:46:46 +00:00
|
|
|
/*
|
|
|
|
* Doesn't like the synchronize cache command.
|
|
|
|
* Reported by: walter@pelissero.de
|
|
|
|
*/
|
2005-04-14 04:12:45 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
|
|
|
|
/*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
2003-12-08 06:29:38 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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) */
|
2003-08-22 05:43:30 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
},
|
2003-08-22 05:58:23 +00:00
|
|
|
{
|
|
|
|
/*
|
2004-04-19 04:14:09 +00:00
|
|
|
* Power Quotient Int. (PQI) USB flash key
|
|
|
|
* PR: kern/53067
|
2003-08-22 05:58:23 +00:00
|
|
|
*/
|
2004-04-19 04:14:09 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*",
|
|
|
|
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
2003-08-22 16:35:53 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
},
|
2004-04-19 04:14:09 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
},
|
2004-05-02 19:24:23 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Neuros USB Digital Audio Computer
|
|
|
|
* PR: kern/63645
|
|
|
|
*/
|
|
|
|
{T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.",
|
|
|
|
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
2004-07-18 05:39:14 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
},
|
2004-08-08 09:08:37 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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
|
2004-08-12 23:17:09 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
|
|
|
|
* PR: kern/70158
|
|
|
|
*/
|
2005-04-14 03:59:48 +00:00
|
|
|
{T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
|
2004-08-12 23:17:09 +00:00
|
|
|
/*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
2005-04-14 04:31:48 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+", "*"},
|
|
|
|
/*quirks*/ DA_Q_NO_SYNC_CACHE
|
|
|
|
},
|
1998-10-08 05:46:38 +00:00
|
|
|
};
|
|
|
|
|
2003-02-25 22:06:21 +00:00
|
|
|
static disk_strategy_t dastrategy;
|
2003-02-21 19:00:48 +00:00
|
|
|
static dumper_t dadump;
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
static timeout_t dasendorderedtag;
|
1999-08-21 06:24:40 +00:00
|
|
|
static void dashutdown(void *arg, int howto);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
#ifndef DA_DEFAULT_TIMEOUT
|
|
|
|
#define DA_DEFAULT_TIMEOUT 60 /* Timeout in seconds */
|
|
|
|
#endif
|
|
|
|
|
2001-07-09 19:18:00 +00:00
|
|
|
#ifndef DA_DEFAULT_RETRY
|
|
|
|
#define DA_DEFAULT_RETRY 4
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int da_retry_count = DA_DEFAULT_RETRY;
|
|
|
|
static int da_default_timeout = DA_DEFAULT_TIMEOUT;
|
|
|
|
|
|
|
|
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);
|
2001-07-09 19:18:00 +00:00
|
|
|
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);
|
2001-07-09 19:18:00 +00:00
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
};
|
|
|
|
|
2001-02-07 07:05:59 +00:00
|
|
|
PERIPHDRIVER_DECLARE(da, dadriver);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
2000-05-26 02:09:24 +00:00
|
|
|
static SLIST_HEAD(,da_softc) softc_list;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
static int
|
2003-02-25 22:06:21 +00:00
|
|
|
daopen(struct disk *dp)
|
1998-09-15 06:36:34 +00:00
|
|
|
{
|
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
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();
|
2003-02-25 22:06:21 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
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
|
|
|
}
|
2004-02-22 01:14:54 +00:00
|
|
|
unit = periph->unit_number;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
softc = (struct da_softc *)periph->softc;
|
|
|
|
|
|
|
|
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
|
2003-02-25 22:06:21 +00:00
|
|
|
("daopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit,
|
2002-09-20 16:25:16 +00:00
|
|
|
unit));
|
1998-09-15 06:36:34 +00:00
|
|
|
|
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)
|
1998-09-15 06:36:34 +00:00
|
|
|
return (error); /* error code from tsleep */
|
|
|
|
|
1999-10-01 09:34:10 +00:00
|
|
|
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
|
|
|
|
return(ENXIO);
|
|
|
|
softc->flags |= DA_FLAG_OPEN;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
|
1998-10-07 02:57:57 +00:00
|
|
|
/* Invalidate our pack information. */
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
if (error == 0) {
|
1998-10-07 02:57:57 +00:00
|
|
|
|
2004-02-18 21:36:53 +00:00
|
|
|
softc->disk->d_sectorsize = softc->params.secsize;
|
|
|
|
softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
|
2002-09-20 19:36:05 +00:00
|
|
|
/* XXX: these are not actually "firmware" values, so they may be wrong */
|
2004-02-18 21:36:53 +00:00
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
|
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) {
|
2003-08-22 16:35:53 +00:00
|
|
|
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);
|
2002-11-29 15:40:10 +00:00
|
|
|
} else {
|
2002-12-12 18:09:35 +00:00
|
|
|
softc->flags &= ~DA_FLAG_OPEN;
|
2002-11-29 15:40:10 +00:00
|
|
|
cam_periph_release(periph);
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
cam_periph_unlock(periph);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-02-25 22:06:21 +00:00
|
|
|
daclose(struct disk *dp)
|
1998-09-15 06:36:34 +00:00
|
|
|
{
|
|
|
|
struct cam_periph *periph;
|
|
|
|
struct da_softc *softc;
|
|
|
|
int error;
|
|
|
|
|
2003-02-25 22:06:21 +00:00
|
|
|
periph = (struct cam_periph *)dp->d_drv1;
|
1998-09-15 06:36:34 +00:00
|
|
|
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 */
|
|
|
|
}
|
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
|
|
|
|
union ccb *ccb;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
ccb = cam_periph_getccb(periph, /*priority*/1);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
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,
|
2004-02-18 21:36:53 +00:00
|
|
|
softc->disk->d_devstat);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1999-03-05 23:20:20 +00:00
|
|
|
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_path(periph->path);
|
|
|
|
printf("Synchronize cache failed, status "
|
|
|
|
"== 0x%x, scsi status == 0x%x\n",
|
|
|
|
ccb->csio.ccb_h.status,
|
|
|
|
ccb->csio.scsi_status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-10-08 05:46:38 +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);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
xpt_release_ccb(ccb);
|
|
|
|
|
|
|
|
}
|
1998-09-19 04:59:35 +00:00
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
|
2003-08-22 16:35:53 +00:00
|
|
|
if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
|
|
|
|
daprevent(periph, PR_ALLOW);
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
|
|
|
* If we've got removeable media, mark the blocksize as
|
|
|
|
* unavailable, since it could change when new media is
|
|
|
|
* inserted.
|
|
|
|
*/
|
2004-02-18 21:36:53 +00:00
|
|
|
softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2000-04-15 05:54:02 +00:00
|
|
|
dastrategy(struct bio *bp)
|
1998-09-15 06:36:34 +00:00
|
|
|
{
|
|
|
|
struct cam_periph *periph;
|
|
|
|
struct da_softc *softc;
|
|
|
|
int s;
|
|
|
|
|
2003-02-25 22:06:21 +00:00
|
|
|
periph = (struct cam_periph *)bp->bio_disk->d_drv1;
|
1998-09-15 06:36:34 +00:00
|
|
|
if (periph == NULL) {
|
2001-05-08 08:30:48 +00:00
|
|
|
biofinish(bp, NULL, ENXIO);
|
|
|
|
return;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
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);
|
2001-05-08 08:30:48 +00:00
|
|
|
biofinish(bp, NULL, ENXIO);
|
|
|
|
return;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Place it in the queue of disk activities for this disk
|
|
|
|
*/
|
2003-04-01 15:06:26 +00:00
|
|
|
bioq_disksort(&softc->bio_queue, bp);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
splx(s);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Schedule ourselves for performing the work.
|
|
|
|
*/
|
|
|
|
xpt_schedule(periph, /* XXX priority */1);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-02-21 19:00:48 +00:00
|
|
|
dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
|
1998-09-15 06:36:34 +00:00
|
|
|
{
|
1998-12-11 03:54:43 +00:00
|
|
|
struct cam_periph *periph;
|
|
|
|
struct da_softc *softc;
|
1999-10-01 09:34:10 +00:00
|
|
|
u_int secsize;
|
1998-12-11 03:54:43 +00:00
|
|
|
struct ccb_scsiio csio;
|
2003-02-21 19:00:48 +00:00
|
|
|
struct disk *dp;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
2003-02-21 19:00:48 +00:00
|
|
|
dp = arg;
|
2003-02-25 22:06:21 +00:00
|
|
|
periph = dp->d_drv1;
|
2002-03-31 22:28:03 +00:00
|
|
|
if (periph == NULL)
|
1998-09-15 06:36:34 +00:00
|
|
|
return (ENXIO);
|
|
|
|
softc = (struct da_softc *)periph->softc;
|
2002-03-31 22:28:03 +00:00
|
|
|
secsize = softc->params.secsize;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1999-10-01 09:34:10 +00:00
|
|
|
if ((softc->flags & DA_FLAG_PACK_INVALID) != 0)
|
1998-09-15 06:36:34 +00:00
|
|
|
return (ENXIO);
|
|
|
|
|
2002-03-31 22:28:03 +00:00
|
|
|
if (length > 0) {
|
1998-09-15 06:36:34 +00:00
|
|
|
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,
|
1998-12-02 17:35:28 +00:00
|
|
|
/*minimum_cmd_size*/ softc->minimum_cmd_size,
|
2002-03-31 22:28:03 +00:00
|
|
|
offset / secsize,
|
|
|
|
length / secsize,
|
|
|
|
/*data_ptr*/(u_int8_t *) virtual,
|
|
|
|
/*dxfer_len*/length,
|
1998-09-15 06:36:34 +00:00
|
|
|
/*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) {
|
1998-10-08 05:46:38 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
2002-03-31 22:28:03 +00:00
|
|
|
return(0);
|
|
|
|
}
|
1998-09-15 06:36:34 +00:00
|
|
|
|
1998-10-08 05:46:38 +00:00
|
|
|
/*
|
|
|
|
* 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) ==
|
1999-03-05 23:20:20 +00:00
|
|
|
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 {
|
1998-10-08 05:46:38 +00:00
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("Synchronize cache failed, status "
|
|
|
|
"== 0x%x, scsi status == 0x%x\n",
|
|
|
|
csio.ccb_h.status, csio.scsi_status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-09-15 06:36:34 +00:00
|
|
|
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 {
|
1998-10-08 05:46:38 +00:00
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
2001-07-09 19:18:00 +00:00
|
|
|
* Schedule a periodic event to occasionally send an
|
1998-09-15 06:36:34 +00:00
|
|
|
* ordered tag to a device.
|
|
|
|
*/
|
|
|
|
timeout(dasendorderedtag, NULL,
|
|
|
|
(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
|
1998-10-08 05:46:38 +00:00
|
|
|
|
1999-08-21 06:24:40 +00:00
|
|
|
/* 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)
|
1999-08-21 06:24:40 +00:00
|
|
|
printf("dainit: shutdown event registration failed!\n");
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
*/
|
2003-04-01 15:06:26 +00:00
|
|
|
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);
|
|
|
|
|
2000-05-26 02:09:24 +00:00
|
|
|
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
|
|
|
|
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("lost device\n");
|
|
|
|
}
|
|
|
|
|
1998-09-15 06:36:34 +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;
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("removing device entry\n");
|
2003-03-26 04:38:39 +00:00
|
|
|
/*
|
|
|
|
* If we can't free the sysctl tree, oh well...
|
|
|
|
*/
|
2003-10-08 07:12:30 +00:00
|
|
|
if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
|
|
|
|
&& sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
|
2003-03-26 04:38:39 +00:00
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("can't remove sysctl context\n");
|
|
|
|
}
|
2004-02-18 21:36:53 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2001-07-04 05:22:42 +00:00
|
|
|
if (cgd == NULL)
|
|
|
|
break;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
2000-01-17 06:27:37 +00:00
|
|
|
if (SID_TYPE(&cgd->inq_data) != T_DIRECT
|
2002-02-21 11:58:47 +00:00
|
|
|
&& SID_TYPE(&cgd->inq_data) != T_RBC
|
2000-01-17 06:27:37 +00:00
|
|
|
&& SID_TYPE(&cgd->inq_data) != T_OPTICAL)
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
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;
|
2001-02-04 13:13:25 +00:00
|
|
|
LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
|
1998-09-15 06:36:34 +00:00
|
|
|
ccbh->ccb_state |= DA_CCB_RETRY_UA;
|
|
|
|
splx(s);
|
1999-05-22 22:00:24 +00:00
|
|
|
/* FALLTHROUGH*/
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
default:
|
1999-05-22 22:00:24 +00:00
|
|
|
cam_periph_async(periph, code, path, arg);
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
2003-10-08 07:12:30 +00:00
|
|
|
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");
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
static cam_status
|
|
|
|
daregister(struct cam_periph *periph, void *arg)
|
|
|
|
{
|
|
|
|
int s;
|
|
|
|
struct da_softc *softc;
|
|
|
|
struct ccb_setasync csa;
|
2003-07-28 06:15:59 +00:00
|
|
|
struct ccb_pathinq cpi;
|
1998-09-15 06:36:34 +00:00
|
|
|
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];
|
1998-10-08 05:46:38 +00:00
|
|
|
caddr_t match;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2002-10-11 09:59:22 +00:00
|
|
|
softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF,
|
|
|
|
M_NOWAIT|M_ZERO);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
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;
|
2000-04-15 05:54:02 +00:00
|
|
|
bioq_init(&softc->bio_queue);
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
1998-10-08 05:46:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2003-07-28 06:15:59 +00:00
|
|
|
/* 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).
|
|
|
|
*/
|
2002-02-21 11:58:47 +00:00
|
|
|
if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
|
1998-12-02 17:35:28 +00:00
|
|
|
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
|
|
|
|
1998-09-15 06:36:34 +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);
|
|
|
|
|
1999-10-01 09:34:10 +00:00
|
|
|
/*
|
|
|
|
* Register this media as a disk
|
|
|
|
*/
|
2003-02-25 22:06:21 +00:00
|
|
|
|
2004-02-18 21:36:53 +00:00
|
|
|
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;
|
|
|
|
disk_create(softc->disk, DISK_VERSION);
|
1999-10-01 09:34:10 +00:00
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
|
|
|
* 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 */
|
2000-04-15 05:54:02 +00:00
|
|
|
struct bio *bp;
|
1998-09-15 06:36:34 +00:00
|
|
|
int s;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See if there is a buf with work for us to do..
|
|
|
|
*/
|
|
|
|
s = splbio();
|
2000-04-15 05:54:02 +00:00
|
|
|
bp = bioq_first(&softc->bio_queue);
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
|
|
|
|
2000-04-15 05:54:02 +00:00
|
|
|
bioq_remove(&softc->bio_queue, bp);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
2002-02-22 09:18:46 +00:00
|
|
|
if ((softc->flags & DA_FLAG_NEED_OTAG) != 0) {
|
1998-09-15 06:36:34 +00:00
|
|
|
softc->flags &= ~DA_FLAG_NEED_OTAG;
|
|
|
|
softc->ordered_tag_count++;
|
|
|
|
tag_code = MSG_ORDERED_Q_TAG;
|
|
|
|
} else {
|
|
|
|
tag_code = MSG_SIMPLE_Q_TAG;
|
|
|
|
}
|
|
|
|
scsi_read_write(&start_ccb->csio,
|
2001-07-09 19:18:00 +00:00
|
|
|
/*retries*/da_retry_count,
|
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
|
|
|
/*cbfcnp*/dadone,
|
|
|
|
/*tag_action*/tag_code,
|
|
|
|
/*read_op*/bp->bio_cmd == BIO_READ,
|
1998-09-15 06:36:34 +00:00
|
|
|
/*byte2*/0,
|
1998-12-02 17:35:28 +00:00
|
|
|
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
|
|
|
/*lba*/bp->bio_pblkno,
|
|
|
|
/*block_count*/bp->bio_bcount /
|
|
|
|
softc->params.secsize,
|
|
|
|
/*data_ptr*/ bp->bio_data,
|
|
|
|
/*dxfer_len*/ bp->bio_bcount,
|
1998-09-15 06:36:34 +00:00
|
|
|
/*sense_len*/SSD_FULL_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
|
|
|
/*timeout*/da_default_timeout*1000);
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
2003-03-15 11:00:56 +00:00
|
|
|
softc->outstanding_cmds++;
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
2000-04-15 05:54:02 +00:00
|
|
|
bp = bioq_first(&softc->bio_queue);
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
|
|
|
}
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-23 18:18:02 +00:00
|
|
|
static int
|
|
|
|
cmd6workaround(union ccb *ccb)
|
|
|
|
{
|
|
|
|
struct scsi_rw_6 cmd6;
|
|
|
|
struct scsi_rw_10 *cmd10;
|
|
|
|
struct da_softc *softc;
|
2002-08-16 22:05:19 +00:00
|
|
|
u_int8_t *cdb;
|
|
|
|
int frozen;
|
2002-03-23 18:18:02 +00:00
|
|
|
|
2002-08-16 22:05:19 +00:00
|
|
|
cdb = ccb->csio.cdb_io.cdb_bytes;
|
2002-03-23 18:18:02 +00:00
|
|
|
|
2002-08-16 22:05:19 +00:00
|
|
|
/* 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))
|
2002-03-23 18:18:02 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
xpt_print_path(ccb->ccb_h.path);
|
2002-08-16 22:05:19 +00:00
|
|
|
printf("READ(6)/WRITE(6) not supported, "
|
|
|
|
"increasing minimum_cmd_size to 10.\n");
|
2002-03-23 18:18:02 +00:00
|
|
|
softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
|
|
|
|
softc->minimum_cmd_size = 10;
|
|
|
|
|
2002-08-16 22:05:19 +00:00
|
|
|
bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
|
|
|
|
cmd10 = (struct scsi_rw_10 *)cdb;
|
2002-03-23 18:18:02 +00:00
|
|
|
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;
|
2002-08-16 22:05:19 +00:00
|
|
|
ccb->csio.cdb_len = sizeof(*cmd10);
|
2002-03-23 18:18:02 +00:00
|
|
|
|
2002-08-16 22:05:19 +00:00
|
|
|
/* Requeue request, unfreezing queue if necessary */
|
|
|
|
frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
|
2002-03-23 18:18:02 +00:00
|
|
|
ccb->ccb_h.status = CAM_REQUEUE_REQ;
|
|
|
|
xpt_action(ccb);
|
2002-08-16 22:05:19 +00:00
|
|
|
if (frozen) {
|
2002-03-23 18:18:02 +00:00
|
|
|
cam_release_devq(ccb->ccb_h.path,
|
|
|
|
/*relsim_flags*/0,
|
|
|
|
/*reduction*/0,
|
|
|
|
/*timeout*/0,
|
|
|
|
/*getcount_only*/0);
|
2002-08-16 22:05:19 +00:00
|
|
|
}
|
2002-03-23 18:18:02 +00:00
|
|
|
return (ERESTART);
|
|
|
|
}
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
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:
|
|
|
|
{
|
2000-04-15 05:54:02 +00:00
|
|
|
struct bio *bp;
|
1998-09-15 06:36:34 +00:00
|
|
|
int oldspl;
|
|
|
|
|
2000-04-15 05:54:02 +00:00
|
|
|
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
|
1998-09-15 06:36:34 +00:00
|
|
|
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) {
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
* change first.
|
|
|
|
*/
|
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("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.
|
|
|
|
*/
|
2003-04-01 15:06:26 +00:00
|
|
|
bioq_flush(&softc->bio_queue, NULL, EIO);
|
1998-09-15 06:36:34 +00:00
|
|
|
splx(s);
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_error = error;
|
|
|
|
bp->bio_resid = bp->bio_bcount;
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
1998-09-15 06:36:34 +00:00
|
|
|
} else {
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_resid = csio->resid;
|
|
|
|
bp->bio_error = 0;
|
2003-08-06 14:24:16 +00:00
|
|
|
if (bp->bio_resid != 0)
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_flags |= BIO_ERROR;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
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");
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_resid = csio->resid;
|
2003-08-06 14:24:16 +00:00
|
|
|
if (csio->resid > 0)
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_flags |= BIO_ERROR;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Block out any asyncronous callbacks
|
|
|
|
* while we touch the pending ccb list.
|
|
|
|
*/
|
|
|
|
oldspl = splcam();
|
|
|
|
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
|
2003-03-15 11:00:56 +00:00
|
|
|
softc->outstanding_cmds--;
|
|
|
|
if (softc->outstanding_cmds == 0)
|
1998-09-15 06:36:34 +00:00
|
|
|
softc->flags |= DA_FLAG_WENT_IDLE;
|
2003-03-15 11:00:56 +00:00
|
|
|
splx(oldspl);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
2003-03-08 08:01:31 +00:00
|
|
|
biodone(bp);
|
1998-09-15 06:36:34 +00:00
|
|
|
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:
|
1998-09-15 06:36:34 +00:00
|
|
|
{
|
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
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);
|
2003-05-03 00:21:40 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
dasetgeom(periph, block_size, maxsector);
|
1998-09-15 06:36:34 +00:00
|
|
|
dp = &softc->params;
|
1998-12-04 22:54:57 +00:00
|
|
|
snprintf(announce_buf, sizeof(announce_buf),
|
2003-04-30 13:36:51 +00:00
|
|
|
"%juMB (%ju %u byte sectors: %dH %dS/T %dC)",
|
|
|
|
(uintmax_t) (((uintmax_t)dp->secsize *
|
|
|
|
dp->sectors) / (1024*1024)),
|
|
|
|
(uintmax_t)dp->sectors,
|
1999-07-07 18:14:01 +00:00
|
|
|
dp->secsize, dp->heads, dp->secs_per_track,
|
|
|
|
dp->cylinders);
|
1998-09-15 06:36:34 +00:00
|
|
|
} else {
|
|
|
|
int error;
|
|
|
|
|
1999-08-15 23:34:40 +00:00
|
|
|
announce_buf[0] = '\0';
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
|
|
|
* 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);
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
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.
|
1998-09-15 06:36:34 +00:00
|
|
|
*/
|
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);
|
1998-12-04 22:54:57 +00:00
|
|
|
snprintf(announce_buf,
|
|
|
|
sizeof(announce_buf),
|
1998-09-15 06:36:34 +00:00
|
|
|
"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 {
|
1998-10-07 02:57:57 +00:00
|
|
|
if (have_sense)
|
|
|
|
scsi_sense_print(
|
|
|
|
&done_ccb->csio);
|
|
|
|
else {
|
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("got CAM status %#x\n",
|
|
|
|
done_ccb->ccb_h.status);
|
|
|
|
}
|
1999-01-07 20:19:09 +00:00
|
|
|
|
1998-10-07 02:57:57 +00:00
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("fatal error, failed"
|
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
|
|
|
" to attach to device\n");
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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') {
|
1998-09-15 06:36:34 +00:00
|
|
|
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;
|
1999-01-07 20:19:09 +00:00
|
|
|
/*
|
|
|
|
* 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);
|
1998-10-07 02:57:57 +00:00
|
|
|
cam_periph_unlock(periph);
|
1999-01-07 20:19:09 +00:00
|
|
|
return;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
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;
|
1999-01-07 20:19:09 +00:00
|
|
|
default:
|
|
|
|
break;
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
1999-01-07 20:19:09 +00:00
|
|
|
xpt_release_ccb(done_ccb);
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
periph = xpt_path_periph(ccb->ccb_h.path);
|
|
|
|
softc = (struct da_softc *)periph->softc;
|
|
|
|
|
2002-03-23 18:18:02 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2002-03-23 18:18:02 +00:00
|
|
|
scsi_extract_sense(&ccb->csio.sense_data,
|
2002-08-16 22:05:19 +00:00
|
|
|
&error_code, &sense_key, &asc, &ascq);
|
2002-03-23 18:18:02 +00:00
|
|
|
if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
|
|
|
|
error = cmd6workaround(ccb);
|
|
|
|
}
|
|
|
|
if (error == ERESTART)
|
2002-08-16 22:05:19 +00:00
|
|
|
return (ERESTART);
|
2002-03-23 18:18:02 +00:00
|
|
|
|
1998-09-20 07:17:11 +00:00
|
|
|
/*
|
|
|
|
* XXX
|
|
|
|
* Until we have a better way of doing pack validation,
|
|
|
|
* don't treat UAs as errors.
|
|
|
|
*/
|
|
|
|
sense_flags |= SF_RETRY_UA;
|
1998-09-15 06:36:34 +00:00
|
|
|
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);
|
|
|
|
|
2001-05-01 19:37:25 +00:00
|
|
|
error = cam_periph_runccb(ccb, /*error_routine*/NULL, CAM_RETRY_SELTO,
|
2004-02-18 21:36:53 +00:00
|
|
|
SF_RETRY_UA, softc->disk->d_devstat);
|
1998-09-15 06:36:34 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
softc = (struct da_softc *)periph->softc;
|
2003-05-01 05:16:13 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
/* 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*/SF_RETRY_UA,
|
2004-02-18 21:36:53 +00:00
|
|
|
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*/SF_RETRY_UA,
|
2004-02-18 21:36:53 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
1998-09-15 06:36:34 +00:00
|
|
|
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)
|
1998-09-15 06:36:34 +00:00
|
|
|
{
|
|
|
|
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;
|
1998-09-15 06:36:34 +00:00
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2003-03-15 11:00:56 +00:00
|
|
|
if (softc->outstanding_cmds > 0)
|
1998-09-15 06:36:34 +00:00
|
|
|
softc->flags &= ~DA_FLAG_WENT_IDLE;
|
|
|
|
|
|
|
|
softc->ordered_tag_count = 0;
|
|
|
|
splx(s);
|
|
|
|
}
|
|
|
|
/* Queue us up again */
|
|
|
|
timeout(dasendorderedtag, NULL,
|
2001-07-09 19:18:00 +00:00
|
|
|
(da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL);
|
1998-09-15 06:36:34 +00:00
|
|
|
}
|
1998-10-08 05:46:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Step through all DA peripheral drivers, and if the device is still open,
|
|
|
|
* sync the disk cache to physical media.
|
|
|
|
*/
|
|
|
|
static void
|
1999-08-21 06:24:40 +00:00
|
|
|
dashutdown(void * arg, int howto)
|
1998-10-08 05:46:38 +00:00
|
|
|
{
|
|
|
|
struct cam_periph *periph;
|
|
|
|
struct da_softc *softc;
|
|
|
|
|
2001-02-04 16:08:18 +00:00
|
|
|
TAILQ_FOREACH(periph, &dadriver.units, unit_links) {
|
1998-10-08 05:46:38 +00:00
|
|
|
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,
|
2001-11-17 18:26:00 +00:00
|
|
|
60 * 60 * 1000);
|
1998-10-08 05:46:38 +00:00
|
|
|
|
|
|
|
xpt_polled_action(&ccb);
|
|
|
|
|
|
|
|
if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
1998-10-12 17:16:47 +00:00
|
|
|
if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
|
1998-10-08 05:46:38 +00:00
|
|
|
CAM_SCSI_STATUS_ERROR)
|
1998-10-12 17:16:47 +00:00
|
|
|
&& (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 {
|
1998-10-08 05:46:38 +00:00
|
|
|
xpt_print_path(periph->path);
|
|
|
|
printf("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);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2000-05-21 23:57:52 +00:00
|
|
|
|
|
|
|
#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 */
|