From owner-freebsd-scsi Sun Nov 10 6:20:14 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 140CE37B401 for ; Sun, 10 Nov 2002 06:20:14 -0800 (PST) Received: from sax.sax.de (sax.sax.de [193.175.26.33]) by mx1.FreeBSD.org (Postfix) with ESMTP id B74EC43E42 for ; Sun, 10 Nov 2002 06:20:12 -0800 (PST) (envelope-from j@uriah.heep.sax.de) Received: (from uucp@localhost) by sax.sax.de (8.9.3/8.9.3) with UUCP id PAA16228 for freebsd-scsi@freebsd.org; Sun, 10 Nov 2002 15:20:05 +0100 (CET) Received: from uriah.heep.sax.de (localhost.heep.sax.de [127.0.0.1]) by uriah.heep.sax.de (8.12.5/8.12.5) with ESMTP id gAAEHVWc063061 for ; Sun, 10 Nov 2002 15:17:31 +0100 (MET) (envelope-from j@uriah.heep.sax.de) Received: (from j@localhost) by uriah.heep.sax.de (8.12.5/8.12.5/Submit) id gAAEHU63063060; Sun, 10 Nov 2002 15:17:30 +0100 (MET) (envelope-from j) Date: Sun, 10 Nov 2002 15:17:30 +0100 (MET) Message-Id: <200211101417.gAAEHU63063060@uriah.heep.sax.de> Mime-Version: 1.0 X-Newsreader: knews 1.0b.1 Reply-To: joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch) Organization: Private BSD site, Dresden X-Phone: +49-351-2012 669 X-PGP-Fingerprint: DC 47 E6 E4 FF A6 E9 8F 93 21 E0 7D F9 12 D6 4E References: <3DCDD987.337479DF@alum.mit.edu> From: j@uriah.heep.sax.de (Joerg Wunsch) Subject: Re: nca (NCR5380) X-Original-Newsgroups: local.freebsd.scsi To: freebsd-scsi@freebsd.org Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Jed Clear wrote: > I've got a UMAX 1220S Scanner with the UDS-IS11 (DTC-3181) SCSI > controller that I'd like to get working under 4.7. Better obtain a cheap AHA-1542C instead. You should get them for close to nothing now. Or use a PCI Symbios Logic 53c810-based one instead. -- cheers, J"org .-.-. --... ...-- -.. . DL8DTL http://www.sax.de/~joerg/ NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Sun Nov 10 23:34:58 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E912C37B401 for ; Sun, 10 Nov 2002 23:34:57 -0800 (PST) Received: from gasdob.com.ua (gasdob.com.ua [212.9.225.82]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5B63A43E3B for ; Sun, 10 Nov 2002 23:34:48 -0800 (PST) (envelope-from kuritex@mail.i.com.ua) Received: (from root@localhost) by gasdob.com.ua (8.11.3/8.11.3) id gAB7af177311 for freebsd-scsi@FreeBSD.ORG.KAV; Mon, 11 Nov 2002 09:36:41 +0200 (EET) (envelope-from kuritex@mail.i.com.ua) Received: from BASHKIROV (kurita.gasdob.com.ua [10.20.0.95]) by gasdob.com.ua (8.11.3/8.11.3) with ESMTP id gAB7aXc77302 for ; Mon, 11 Nov 2002 09:36:40 +0200 (EET) (envelope-from kuritex@mail.i.com.ua) Date: Mon, 11 Nov 2002 09:34:54 +0200 From: Kuritex X-Mailer: The Bat! (v1.42f) Educational Reply-To: Kuritex X-Priority: 3 (Normal) Message-ID: <1533795648.20021111093454@mail.i.com.ua> To: freebsd-scsi@FreeBSD.ORG Subject: FreeBSD on the HP's tc2100/SCSI-version Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Hello all subscribers, Gonna upgrade our corporative mail-server (common PII running FreeBSD, of course) up to the brand hardware, namely HP's tc2100 server model (1.3 GHz PIII, SCSI-version shipping single-channel SCSI-controller). So the following question appears: is there any hidden rocks in the FreeBSD 4.5 installation on this HP model (as far as 'Flexibility' section in tc2100 data sheet doesn't list FreeBSD as a supported OS) and what are the possible troubles I may clash during installation? Anyway, has anybody here experienced installing FreeBSD distributive on tc2100? TIA, Leonid G. Bashkirov To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Sun Nov 10 23:48:42 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4CD6137B401 for ; Sun, 10 Nov 2002 23:47:38 -0800 (PST) Received: from panzer.kdm.org (panzer.kdm.org [216.160.178.169]) by mx1.FreeBSD.org (Postfix) with ESMTP id 049A743E4A for ; Sun, 10 Nov 2002 23:47:32 -0800 (PST) (envelope-from ken@panzer.kdm.org) Received: from panzer.kdm.org (localhost [127.0.0.1]) by panzer.kdm.org (8.12.5/8.12.5) with ESMTP id gAB7lOKD084444 for ; Mon, 11 Nov 2002 00:47:24 -0700 (MST) (envelope-from ken@panzer.kdm.org) Received: (from ken@localhost) by panzer.kdm.org (8.12.5/8.12.5/Submit) id gAB7lOew084443 for scsi@FreeBSD.org; Mon, 11 Nov 2002 00:47:24 -0700 (MST) (envelope-from ken) Date: Mon, 11 Nov 2002 00:47:24 -0700 From: "Kenneth D. Merry" To: scsi@FreeBSD.org Subject: mode sense/mode select patches for cd(4) Message-ID: <20021111004723.A84290@panzer.kdm.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="ikeVEW9yuYc//A+q" Content-Disposition: inline User-Agent: Mutt/1.2.5.1i Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org --ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Okay, here are patches against -current (first set) and -stable (second set) to add automatic detection of drives that can't handle 6 byte mode sense and mode select. I'd appreciate it if folks could test this, especially people with CDROM drives running via usb, firewire, or ATAPICAM, but also people with older SCSI CDROM drives. To test this, apply the patch (for -current or -stable as appropriate) and do the following: cdcontrol status cdcontrol info cdcontrol play (make sure audio comes out) cdcontrol next (make sure it skips to the next track here) If you get an error after running 'cdcontrol status', try it again. The error reporting when we turn on 10-byte commands is a bit verbose at the moment, so don't worry about that. You shouldn't get an error after the second invocation of 'cdcontrol status'. If you get an error in response to 'cdcontrol next', definitely let me know what kind of drive you have (dmesg is fine) and how it is hooked up (SCSI, firewire, ATAPICAM, usb, etc.). The SCSI-2 PLAY_TRACK command has apparantly been deprecated in the MMC specs, so some drives don't support it. I'd like to get a handle on which ones do and don't, if possible. (The work around isn't hard, but isn't in this patch.) Reports of success or failure are welcome. ======= Now for more details.... When we get an illegal request in response to a 6 byte mode sense or mode select, we reformat the command to be a 10-byte mode sense or mode select and reissue it. These patches also work with drives that do not return block descriptors (even when dbd is 0 in the mode sense command), and drives that return multiple block descriptors. (They work better with the former than the latter; with the latter, they mostly just bail out.) While commands like READ(6) and WRITE(6) can be translated down in the SIM driver, like the ATAPICAM and usb code do, MODE_SENSE(6) and MODE_SELECT(6) cannot be translated, because the 10-byte version of the parameter list is longer. This means that when, e.g., a MODE_SENSE(6) command is translated to a MODE_SENSE(10) command, the page will likely be truncated (unless more space is allocated than needed), and since the peripheral driver code isn't expecting the returned data to be in MODE_SENSE(10) format, it'll be looking in the wrong place for the mode page. The SIM drivers have no way of knowing how long the buffer is that they've been given for a mode sense or mode select, so they can't just up the dxfer_len, change the CDB and call it good. The only way to do translation effectively for these two commands is where the buffer was originally allocated -- in the peripheral driver. So I have implemented translation and 10-byte mode sense and mode select for the cd(4) driver. Why do translation? Why not just default to 10-byte commands? Because some SCSI CDROM drives, maybe quite a few, don't support 10 byte mode sense and mode select. (The 8x Plextor in my test box doesn't, for example.) The right way to do this, eventually, is with the CAM_NEW_TRAN_CODE. 6byte/10byte can be a function of the protocol, and we can hopefully select the right size command up front. It will take a lot of infrastructure work to make it happen, but that functionality will hopefully solve several problems. One thing we need to do, regardless of when these patches go in, is disable MODE_SENSE(6) and MODE_SELECT(6) translation in ATAPICAM and the usb code -- it can't work properly, for the reasons I outlined above. Comments are welcome on the patches; they're more complicated than I would like, but unfortunately that complication seems necessary to get the desired functionality. These patches are not quite in their final form -- some of the debugging output will be turned off, and I have yet to add a loader tuneable or sysctl variable to control the 6 byte / 10 byte switch. Many thanks to David Kleiner for testing multiple iterations of these patches, he has been a big help. Ken -- Kenneth Merry ken@kdm.org --ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="scsi_cd.cmdsize.20021109" ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_all.c#22 - /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_all.c ==== *** /tmp/tmp.269.0 Sat Nov 9 23:26:58 2002 --- /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_all.c Thu Oct 17 23:19:51 2002 *************** *** 2447,2458 **** u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if (param_len < 256) { /* * We can fit in a 6 byte cdb. */ --- 2447,2470 ---- u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { + return(scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd, + page_code, page, param_buf, param_len, 0, + sense_len, timeout)); + } + void + scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, int dbd, u_int8_t page_code, + u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, + int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout) + { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if ((param_len < 256) ! && (minimum_cmd_size < 10)) { /* * We can fit in a 6 byte cdb. */ *************** *** 2500,2511 **** u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if (param_len < 256) { /* * We can fit in a 6 byte cdb. */ --- 2512,2537 ---- u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { + return(scsi_mode_select_len(csio, retries, cbfcnp, tag_action, + scsi_page_fmt, save_pages, param_buf, + param_len, 0, sense_len, timeout)); + } + + void + scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, int scsi_page_fmt, int save_pages, + u_int8_t *param_buf, u_int32_t param_len, + int minimum_cmd_size, u_int8_t sense_len, + u_int32_t timeout) + { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if ((param_len < 256) ! && (minimum_cmd_size < 10)) { /* * We can fit in a 6 byte cdb. */ ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_all.h#11 - /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_all.h ==== *** /tmp/tmp.269.1 Sat Nov 9 23:26:58 2002 --- /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_all.h Thu Oct 17 23:19:51 2002 *************** *** 926,931 **** --- 926,940 ---- u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout); + void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, + union ccb *), + u_int8_t tag_action, int dbd, + u_int8_t page_code, u_int8_t page, + u_int8_t *param_buf, u_int32_t param_len, + int minimum_cmd_size, u_int8_t sense_len, + u_int32_t timeout); + void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), *************** *** 933,938 **** --- 942,955 ---- int save_pages, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout); + + void scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, + union ccb *), + u_int8_t tag_action, int scsi_page_fmt, + int save_pages, u_int8_t *param_buf, + u_int32_t param_len, int minimum_cmd_size, + u_int8_t sense_len, u_int32_t timeout); void scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c#28 - /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c ==== *** /tmp/tmp.269.2 Sat Nov 9 23:26:58 2002 --- /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c Sat Nov 9 23:00:06 2002 *************** *** 1,6 **** /* * Copyright (c) 1997 Justin T. Gibbs. ! * Copyright (c) 1997, 1998, 1999, 2000, 2001 Kenneth D. Merry. * All rights reserved. * * Redistribution and use in source and binary forms, with or without --- 1,6 ---- /* * Copyright (c) 1997 Justin T. Gibbs. ! * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 Kenneth D. Merry. * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 137,142 **** --- 137,153 ---- struct cam_periph *periph; dev_t dev; eventhandler_tag clonetag; + int minimum_command_size; + }; + + struct cd_page_sizes { + int page; + int page_size; + }; + + static struct cd_page_sizes cd_page_size_table[] = + { + { AUDIO_PAGE, sizeof(struct cd_audio_page)} }; struct cd_quirk_entry { *************** *** 203,208 **** --- 214,220 ---- u_int32_t priority); static void cddone(struct cam_periph *periph, union ccb *start_ccb); + static int cd6byteworkaround(union ccb *ccb); static int cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); static void cdprevent(struct cam_periph *periph, int action); *************** *** 211,219 **** u_int32_t start, struct cd_toc_entry *data, u_int32_t len); static int cdgetmode(struct cam_periph *periph, ! struct cd_mode_data *data, u_int32_t page); static int cdsetmode(struct cam_periph *periph, ! struct cd_mode_data *data); static int cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len); static int cdreadsubchannel(struct cam_periph *periph, --- 223,231 ---- u_int32_t start, struct cd_toc_entry *data, u_int32_t len); static int cdgetmode(struct cam_periph *periph, ! struct cd_mode_params *data, u_int32_t page); static int cdsetmode(struct cam_periph *periph, ! struct cd_mode_params *data); static int cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len); static int cdreadsubchannel(struct cam_periph *periph, *************** *** 609,614 **** --- 621,628 ---- else softc->quirks = CD_Q_NONE; + softc->minimum_command_size = 6; + /* * We need to register the statistics structure for this device, * but we don't have the blocksize yet for it. So, we register *************** *** 1747,1752 **** --- 1761,1795 ---- xpt_release_ccb(done_ccb); } + static union cd_pages * + cdgetpage(struct cd_mode_params *mode_params) + { + union cd_pages *page; + + if (mode_params->cdb_size == 10) + page = (union cd_pages *)find_mode_page_10( + (struct scsi_mode_header_10 *)mode_params->mode_buf); + else + page = (union cd_pages *)find_mode_page_6( + (struct scsi_mode_header_6 *)mode_params->mode_buf); + + return (page); + } + + static int + cdgetpagesize(int page_num) + { + int i; + + for (i = 0; i < (sizeof(cd_page_size_table)/ + sizeof(cd_page_size_table[0])); i++) { + if (cd_page_size_table[i].page == page_num) + return (cd_page_size_table[i].page_size); + } + + return (-1); + } + static int cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { *************** *** 1785,1807 **** { struct ioc_play_track *args = (struct ioc_play_track *) addr; ! struct cd_mode_data *data; ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYTRACKS\n")); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.flags &= ~CD_PA_SOTC; ! data->page.audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); if (error) break; if (softc->quirks & CD_Q_BCD_TRACKS) { --- 1828,1854 ---- { struct ioc_play_track *args = (struct ioc_play_track *) addr; ! struct cd_mode_params params; ! union cd_pages *page; ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYTRACKS\n")); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.flags &= ~CD_PA_SOTC; ! page->audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); if (error) break; if (softc->quirks & CD_Q_BCD_TRACKS) { *************** *** 1819,1841 **** { struct ioc_play_msf *args = (struct ioc_play_msf *) addr; ! struct cd_mode_data *data; ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYMSF\n")); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.flags &= ~CD_PA_SOTC; ! data->page.audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); if (error) break; error = cdplaymsf(periph, --- 1866,1892 ---- { struct ioc_play_msf *args = (struct ioc_play_msf *) addr; ! struct cd_mode_params params; ! union cd_pages *page; ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYMSF\n")); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.flags &= ~CD_PA_SOTC; ! page->audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); if (error) break; error = cdplaymsf(periph, *************** *** 1851,1873 **** { struct ioc_play_blocks *args = (struct ioc_play_blocks *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYBLOCKS\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.flags &= ~CD_PA_SOTC; ! data->page.audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); if (error) break; error = cdplay(periph, args->blk, args->len); --- 1902,1928 ---- { struct ioc_play_blocks *args = (struct ioc_play_blocks *) addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYBLOCKS\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.flags &= ~CD_PA_SOTC; ! page->audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); if (error) break; error = cdplay(periph, args->blk, args->len); *************** *** 2157,2352 **** break; case CDIOCSETPATCH: { ! struct ioc_patch *arg = (struct ioc_patch *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETPATCH\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = arg->patch[0]; ! data->page.audio.port[RIGHT_PORT].channels = arg->patch[1]; ! data->page.audio.port[2].channels = arg->patch[2]; ! data->page.audio.port[3].channels = arg->patch[3]; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCGETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCGETVOL\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } arg->vol[LEFT_PORT] = ! data->page.audio.port[LEFT_PORT].volume; arg->vol[RIGHT_PORT] = ! data->page.audio.port[RIGHT_PORT].volume; ! arg->vol[2] = data->page.audio.port[2].volume; ! arg->vol[3] = data->page.audio.port[3].volume; ! free(data, M_TEMP); } break; case CDIOCSETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETVOL\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = CHANNEL_0; ! data->page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT]; ! data->page.audio.port[RIGHT_PORT].channels = CHANNEL_1; ! data->page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT]; ! data->page.audio.port[2].volume = arg->vol[2]; ! data->page.audio.port[3].volume = arg->vol[3]; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETMONO: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMONO\n")); ! data = malloc(sizeof(struct cd_mode_data), ! M_TEMP, M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETSTEREO: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETSTEREO\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETMUTE: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMUTE\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = 0; ! data->page.audio.port[RIGHT_PORT].channels = 0; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETLEFT: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETLEFT\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = ! LEFT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = ! LEFT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETRIGHT: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETRIGHT\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = ! RIGHT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = ! RIGHT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCRESUME: --- 2212,2437 ---- break; case CDIOCSETPATCH: { ! struct ioc_patch *arg = (struct ioc_patch *)addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETPATCH\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = arg->patch[0]; ! page->audio.port[RIGHT_PORT].channels = arg->patch[1]; ! page->audio.port[2].channels = arg->patch[2]; ! page->audio.port[3].channels = arg->patch[3]; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCGETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCGETVOL\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf= malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } + page = cdgetpage(¶ms); + arg->vol[LEFT_PORT] = ! page->audio.port[LEFT_PORT].volume; arg->vol[RIGHT_PORT] = ! page->audio.port[RIGHT_PORT].volume; ! arg->vol[2] = page->audio.port[2].volume; ! arg->vol[3] = page->audio.port[3].volume; ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETVOL\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = CHANNEL_0; ! page->audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT]; ! page->audio.port[RIGHT_PORT].channels = CHANNEL_1; ! page->audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT]; ! page->audio.port[2].volume = arg->vol[2]; ! page->audio.port[3].volume = arg->vol[3]; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETMONO: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMONO\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETSTEREO: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETSTEREO\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETMUTE: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMUTE\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(¶ms, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = 0; ! page->audio.port[RIGHT_PORT].channels = 0; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETLEFT: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETLEFT\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = LEFT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETRIGHT: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETRIGHT\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = RIGHT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCRESUME: *************** *** 2521,2534 **** --- 2606,2770 ---- } static int + cd6byteworkaround(union ccb *ccb) + { + u_int8_t *cdb; + struct cam_periph *periph; + struct cd_softc *softc; + struct cd_mode_params *params; + int frozen; + + periph = xpt_path_periph(ccb->ccb_h.path); + softc = (struct cd_softc *)periph->softc; + + cdb = ccb->csio.cdb_io.cdb_bytes; + + if ((ccb->ccb_h.flags & CAM_CDB_POINTER) + || ((cdb[0] != MODE_SENSE_6) + && (cdb[0] != MODE_SELECT_6))) + return (0); + + /* + * Because there is no other convenient place to stash the overall + * cd_mode_params structure pointer, we have to grab it like this. + * This means that ALL MODE_SENSE and MODE_SELECT requests in the + * cd(4) driver MUST go through cdgetmode() and cdsetmode()! + */ + params = (struct cd_mode_params *)(ccb->csio.data_ptr - + __offsetof(struct cd_mode_params, mode_buf)); + + params->cdb_size = 10; + softc->minimum_command_size = 10; + xpt_print_path(ccb->ccb_h.path); + printf("MODE_SENSE(6)/MODE_SELECT(6) failed, increasing " + "minimum CDB size to 10 bytes\n"); + /* XXX KDM remove this */ + printf("CAM Status %#x\n", ccb->ccb_h.status); + printf("SCSI Status %#x\n", ccb->csio.scsi_status); + scsi_sense_print(&ccb->csio); + + if (cdb[0] == MODE_SENSE_6) { + struct scsi_mode_sense_10 ms10; + struct scsi_mode_sense_6 *ms6; + int len; + + ms6 = (struct scsi_mode_sense_6 *)cdb; + + bzero(&ms10, sizeof(ms10)); + ms10.opcode = MODE_SENSE_10; + ms10.byte2 = ms6->byte2; + ms10.page = ms6->page; + + /* + * 10 byte mode header, block descriptor, + * sizeof(union cd_pages) + */ + len = sizeof(struct cd_mode_data_10); + ccb->csio.dxfer_len = len; + + scsi_ulto2b(len, ms10.length); + ms10.control = ms6->control; + bcopy(&ms10, cdb, 10); + ccb->csio.cdb_len = 10; + } else { + struct scsi_mode_select_10 ms10; + struct scsi_mode_select_6 *ms6; + struct scsi_mode_header_6 *header6; + struct scsi_mode_header_10 *header10; + struct scsi_mode_page_header *page_header; + int blk_desc_len, page_num, page_size, len; + + ms6 = (struct scsi_mode_select_6 *)cdb; + + bzero(&ms10, sizeof(ms10)); + ms10.opcode = MODE_SELECT_10; + ms10.byte2 = ms6->byte2; + + header6 = (struct scsi_mode_header_6 *)params->mode_buf; + header10 = (struct scsi_mode_header_10 *)params->mode_buf; + + page_header = find_mode_page_6(header6); + page_num = page_header->page_code; + + blk_desc_len = header6->blk_desc_len; + + page_size = cdgetpagesize(page_num); + + if (page_size != (page_header->page_length + + sizeof(*page_header))) + page_size = page_header->page_length + + sizeof(*page_header); + + len = sizeof(*header10) + blk_desc_len + page_size; + + len = min(params->alloc_len, len); + + /* + * Since the 6 byte parameter header is shorter than the 10 + * byte parameter header, we need to copy the actual mode + * page data, and the block descriptor, if any, so things wind + * up in the right place. The regions will overlap, but + * bcopy() does the right thing. + */ + bcopy(params->mode_buf + sizeof(*header6), + params->mode_buf + sizeof(*header10), + len - sizeof(*header10)); + + /* Make sure these fields are set correctly. */ + scsi_ulto2b(0, header10->data_length); + header10->medium_type = 0; + scsi_ulto2b(blk_desc_len, header10->blk_desc_len); + + ccb->csio.dxfer_len = len; + + scsi_ulto2b(len, ms10.length); + ms10.control = ms6->control; + bcopy(&ms10, cdb, 10); + ccb->csio.cdb_len = 10; + } + + frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0; + ccb->ccb_h.status = CAM_REQUEUE_REQ; + xpt_action(ccb); + if (frozen) { + cam_release_devq(ccb->ccb_h.path, + /*relsim_flags*/0, + /*openings*/0, + /*timeout*/0, + /*getcount_only*/0); + } + + return (ERESTART); + } + + static int cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) { struct cd_softc *softc; struct cam_periph *periph; + int error; periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct cd_softc *)periph->softc; + error = 0; + + if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) + && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) + && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) + && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0) + && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) { + int sense_key, error_code, asc, ascq; + + scsi_extract_sense(&ccb->csio.sense_data, + &error_code, &sense_key, &asc, &ascq); + if (sense_key == SSD_KEY_ILLEGAL_REQUEST) + error = cd6byteworkaround(ccb); + } + + if (error == ERESTART) + return (error); + /* * XXX * Until we have a better way of doing pack validation, *************** *** 2638,2720 **** } static int ! cdgetmode(struct cam_periph *periph, struct cd_mode_data *data, u_int32_t page) { ! struct scsi_mode_sense_6 *scsi_cmd; ! struct ccb_scsiio *csio; union ccb *ccb; int error; ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; ! bzero(data, sizeof(*data)); ! cam_fill_csio(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* flags */ CAM_DIR_IN, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* data_ptr */ (u_int8_t *)data, ! /* dxfer_len */ sizeof(*data), ! /* sense_len */ SSD_FULL_SIZE, ! sizeof(struct scsi_mode_sense_6), ! /* timeout */ 50000); ! scsi_cmd = (struct scsi_mode_sense_6 *)&csio->cdb_io.cdb_bytes; ! bzero (scsi_cmd, sizeof(*scsi_cmd)); ! scsi_cmd->page = page; ! scsi_cmd->length = sizeof(*data) & 0xff; ! scsi_cmd->opcode = MODE_SENSE; error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, /*sense_flags*/SF_RETRY_UA); xpt_release_ccb(ccb); return(error); } static int ! cdsetmode(struct cam_periph *periph, struct cd_mode_data *data) { ! struct scsi_mode_select_6 *scsi_cmd; ! struct ccb_scsiio *csio; union ccb *ccb; int error; ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; error = 0; ! cam_fill_csio(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* flags */ CAM_DIR_OUT, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* data_ptr */ (u_int8_t *)data, ! /* dxfer_len */ sizeof(*data), ! /* sense_len */ SSD_FULL_SIZE, ! sizeof(struct scsi_mode_select_6), ! /* timeout */ 50000); ! scsi_cmd = (struct scsi_mode_select_6 *)&csio->cdb_io.cdb_bytes; ! bzero(scsi_cmd, sizeof(*scsi_cmd)); ! scsi_cmd->opcode = MODE_SELECT; ! scsi_cmd->byte2 |= SMS_PF; ! scsi_cmd->length = sizeof(*data) & 0xff; ! data->header.data_length = 0; ! /* ! * SONY drives do not allow a mode select with a medium_type ! * value that has just been returned by a mode sense; use a ! * medium_type of 0 (Default) instead. ! */ ! data->header.medium_type = 0; error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, /*sense_flags*/SF_RETRY_UA); --- 2874,3051 ---- } + /* + * All MODE_SENSE requests in the cd(4) driver MUST go through this + * routine. See comments in cd6byteworkaround() for details. + */ static int ! cdgetmode(struct cam_periph *periph, struct cd_mode_params *data, ! u_int32_t page) { ! struct ccb_scsiio *csio; ! struct cd_softc *softc; union ccb *ccb; + int param_len; int error; + softc = (struct cd_softc *)periph->softc; + ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; ! data->cdb_size = softc->minimum_command_size; ! if (data->cdb_size < 10) ! param_len = sizeof(struct cd_mode_data); ! else ! param_len = sizeof(struct cd_mode_data_10); ! /* Don't say we've got more room than we actually allocated */ ! param_len = min(param_len, data->alloc_len); ! scsi_mode_sense_len(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* dbd */ 0, ! /* page_code */ SMS_PAGE_CTRL_CURRENT, ! /* page */ page, ! /* param_buf */ data->mode_buf, ! /* param_len */ param_len, ! /* minimum_cmd_size */ softc->minimum_command_size, ! /* sense_len */ SSD_FULL_SIZE, ! /* timeout */ 50000); error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, /*sense_flags*/SF_RETRY_UA); xpt_release_ccb(ccb); + /* + * This is a bit of belt-and-suspenders checking, but if we run + * into a situation where the target sends back multiple block + * descriptors, we might not have enough space in the buffer to + * see the whole mode page. Better to return an error than + * potentially access memory beyond our malloced region. + */ + if (error == 0) { + u_int32_t data_len; + + if (data->cdb_size == 10) { + struct scsi_mode_header_10 *hdr10; + + hdr10 = (struct scsi_mode_header_10 *)data->mode_buf; + data_len = scsi_2btoul(hdr10->data_length); + data_len += sizeof(hdr10->data_length); + } else { + struct scsi_mode_header_6 *hdr6; + + hdr6 = (struct scsi_mode_header_6 *)data->mode_buf; + data_len = hdr6->data_length; + data_len += sizeof(hdr6->data_length); + } + + /* + * Complain if there is more mode data available than we + * allocated space for. This could potentially happen if + * we miscalculated the page length for some reason, if the + * drive returns multiple block descriptors, or if it sets + * the data length incorrectly. + */ + if (data_len > data->alloc_len) { + xpt_print_path(periph->path); + printf("allocated modepage %d length %d < returned " + "length %d\n", page, data->alloc_len, data_len); + + error = ENOSPC; + } + } return(error); } + /* + * All MODE_SELECT requests in the cd(4) driver MUST go through this + * routine. See comments in cd6byteworkaround() for details. + */ static int ! cdsetmode(struct cam_periph *periph, struct cd_mode_params *data) { ! struct ccb_scsiio *csio; ! struct cd_softc *softc; union ccb *ccb; + int cdb_size, param_len; int error; + softc = (struct cd_softc *)periph->softc; + ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; error = 0; ! /* ! * If the data is formatted for the 10 byte version of the mode ! * select parameter list, we need to use the 10 byte CDB. ! * Otherwise, we use whatever the stored minimum command size. ! */ ! if (data->cdb_size == 10) ! cdb_size = data->cdb_size; ! else ! cdb_size = softc->minimum_command_size; ! if (cdb_size >= 10) { ! struct scsi_mode_header_10 *mode_header; ! u_int32_t data_len; ! mode_header = (struct scsi_mode_header_10 *)data->mode_buf; ! ! data_len = scsi_2btoul(mode_header->data_length); ! ! scsi_ulto2b(0, mode_header->data_length); ! /* ! * SONY drives do not allow a mode select with a medium_type ! * value that has just been returned by a mode sense; use a ! * medium_type of 0 (Default) instead. ! */ ! mode_header->medium_type = 0; ! ! /* ! * Pass back whatever the drive passed to us, plus the size ! * of the data length field. ! */ ! param_len = data_len + sizeof(mode_header->data_length); ! ! } else { ! struct scsi_mode_header_6 *mode_header; ! ! mode_header = (struct scsi_mode_header_6 *)data->mode_buf; ! ! param_len = mode_header->data_length + 1; ! ! mode_header->data_length = 0; ! /* ! * SONY drives do not allow a mode select with a medium_type ! * value that has just been returned by a mode sense; use a ! * medium_type of 0 (Default) instead. ! */ ! mode_header->medium_type = 0; ! } ! ! /* Don't say we've got more room than we actually allocated */ ! param_len = min(param_len, data->alloc_len); ! ! scsi_mode_select_len(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* scsi_page_fmt */ 1, ! /* save_pages */ 0, ! /* param_buf */ data->mode_buf, ! /* param_len */ param_len, ! /* minimum_cmd_size */ cdb_size, ! /* sense_len */ SSD_FULL_SIZE, ! /* timeout */ 50000); error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO, /*sense_flags*/SF_RETRY_UA); ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.h#5 - /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.h ==== *** /tmp/tmp.269.3 Sat Nov 9 23:26:58 2002 --- /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.h Fri Nov 8 22:49:52 2002 *************** *** 655,692 **** u_int8_t length_0; /* Least significant */ }; ! union cd_pages { ! struct audio_page { ! u_int8_t page_code; ! #define CD_PAGE_CODE 0x3F ! #define AUDIO_PAGE 0x0e ! #define CD_PAGE_PS 0x80 ! u_int8_t param_len; ! u_int8_t flags; ! #define CD_PA_SOTC 0x02 ! #define CD_PA_IMMED 0x04 ! u_int8_t unused[2]; ! u_int8_t format_lba; ! #define CD_PA_FORMAT_LBA 0x0F ! #define CD_PA_APR_VALID 0x80 ! u_int8_t lb_per_sec[2]; ! struct port_control ! { ! u_int8_t channels; ! #define CHANNEL 0x0F ! #define CHANNEL_0 1 ! #define CHANNEL_1 2 ! #define CHANNEL_2 4 ! #define CHANNEL_3 8 ! #define LEFT_CHANNEL CHANNEL_0 ! #define RIGHT_CHANNEL CHANNEL_1 ! u_int8_t volume; ! } port[4]; ! #define LEFT_PORT 0 ! #define RIGHT_PORT 1 ! }audio; }; struct cd_mode_data --- 655,701 ---- u_int8_t length_0; /* Least significant */ }; ! struct cd_audio_page { ! u_int8_t page_code; ! #define CD_PAGE_CODE 0x3F ! #define AUDIO_PAGE 0x0e ! #define CD_PAGE_PS 0x80 ! u_int8_t param_len; ! u_int8_t flags; ! #define CD_PA_SOTC 0x02 ! #define CD_PA_IMMED 0x04 ! u_int8_t unused[2]; ! u_int8_t format_lba; ! #define CD_PA_FORMAT_LBA 0x0F ! #define CD_PA_APR_VALID 0x80 ! u_int8_t lb_per_sec[2]; ! struct port_control { ! u_int8_t channels; ! #define CHANNEL 0x0F ! #define CHANNEL_0 1 ! #define CHANNEL_1 2 ! #define CHANNEL_2 4 ! #define CHANNEL_3 8 ! #define LEFT_CHANNEL CHANNEL_0 ! #define RIGHT_CHANNEL CHANNEL_1 ! u_int8_t volume; ! } port[4]; ! #define LEFT_PORT 0 ! #define RIGHT_PORT 1 ! }; ! ! union cd_pages ! { ! struct cd_audio_page audio; ! }; ! ! struct cd_mode_data_10 ! { ! struct scsi_mode_header_10 header; ! struct scsi_mode_blk_desc blk_desc; ! union cd_pages page; }; struct cd_mode_data *************** *** 694,699 **** --- 703,729 ---- struct scsi_mode_header_6 header; struct scsi_mode_blk_desc blk_desc; union cd_pages page; + }; + + union cd_mode_data_6_10 + { + struct cd_mode_data mode_data_6; + struct cd_mode_data_10 mode_data_10; + }; + + #if 0 + struct cd_mode_params + { + int cdb_size; + union cd_mode_data_6_10 mode_data; + }; + #endif + + struct cd_mode_params + { + int cdb_size; + int alloc_len; + u_int8_t *mode_buf; }; __BEGIN_DECLS --ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="scsi_cd.cmdsize.stable.20021109" ==== //depot/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_all.c#7 - /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_all.c ==== *** /tmp/tmp.1941.0 Sat Nov 9 23:41:11 2002 --- /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_all.c Sat Nov 9 23:30:37 2002 *************** *** 2568,2579 **** u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if (param_len < 256) { /* * We can fit in a 6 byte cdb. */ --- 2568,2591 ---- u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { + return(scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd, + page_code, page, param_buf, param_len, 0, + sense_len, timeout)); + } + void + scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, int dbd, u_int8_t page_code, + u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, + int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout) + { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if ((param_len < 256) ! && (minimum_cmd_size < 10)) { /* * We can fit in a 6 byte cdb. */ *************** *** 2621,2632 **** u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if (param_len < 256) { /* * We can fit in a 6 byte cdb. */ --- 2633,2658 ---- u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout) { + return(scsi_mode_select_len(csio, retries, cbfcnp, tag_action, + scsi_page_fmt, save_pages, param_buf, + param_len, 0, sense_len, timeout)); + } + + void + scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, int scsi_page_fmt, int save_pages, + u_int8_t *param_buf, u_int32_t param_len, + int minimum_cmd_size, u_int8_t sense_len, + u_int32_t timeout) + { u_int8_t cdb_len; /* * Use the smallest possible command to perform the operation. */ ! if ((param_len < 256) ! && (minimum_cmd_size < 10)) { /* * We can fit in a 6 byte cdb. */ ==== //depot/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_all.h#2 - /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_all.h ==== *** /tmp/tmp.1941.1 Sat Nov 9 23:41:11 2002 --- /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_all.h Sat Nov 9 23:30:37 2002 *************** *** 833,838 **** --- 833,847 ---- u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout); + void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, + union ccb *), + u_int8_t tag_action, int dbd, + u_int8_t page_code, u_int8_t page, + u_int8_t *param_buf, u_int32_t param_len, + int minimum_cmd_size, u_int8_t sense_len, + u_int32_t timeout); + void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), *************** *** 840,845 **** --- 849,862 ---- int save_pages, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout); + + void scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, + union ccb *), + u_int8_t tag_action, int scsi_page_fmt, + int save_pages, u_int8_t *param_buf, + u_int32_t param_len, int minimum_cmd_size, + u_int8_t sense_len, u_int32_t timeout); void scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, ==== //depot/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_cd.c#6 - /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_cd.c ==== *** /tmp/tmp.1941.2 Sat Nov 9 23:41:11 2002 --- /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_cd.c Sat Nov 9 23:39:54 2002 *************** *** 1,6 **** /* * Copyright (c) 1997 Justin T. Gibbs. ! * Copyright (c) 1997, 1998, 1999, 2000, 2001 Kenneth D. Merry. * All rights reserved. * * Redistribution and use in source and binary forms, with or without --- 1,6 ---- /* * Copyright (c) 1997 Justin T. Gibbs. ! * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 Kenneth D. Merry. * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 136,141 **** --- 136,152 ---- struct cdchanger *changer; int bufs_left; struct cam_periph *periph; + int minimum_command_size; + }; + + struct cd_page_sizes { + int page; + int page_size; + }; + + static struct cd_page_sizes cd_page_size_table[] = + { + { AUDIO_PAGE, sizeof(struct cd_audio_page)} }; struct cd_quirk_entry { *************** *** 203,208 **** --- 214,220 ---- u_int32_t priority); static void cddone(struct cam_periph *periph, union ccb *start_ccb); + static int cd6byteworkaround(union ccb *ccb); static int cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); static void cdprevent(struct cam_periph *periph, int action); *************** *** 212,220 **** u_int32_t start, struct cd_toc_entry *data, u_int32_t len); static int cdgetmode(struct cam_periph *periph, ! struct cd_mode_data *data, u_int32_t page); static int cdsetmode(struct cam_periph *periph, ! struct cd_mode_data *data); static int cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len); static int cdreadsubchannel(struct cam_periph *periph, --- 224,232 ---- u_int32_t start, struct cd_toc_entry *data, u_int32_t len); static int cdgetmode(struct cam_periph *periph, ! struct cd_mode_params *data, u_int32_t page); static int cdsetmode(struct cam_periph *periph, ! struct cd_mode_params *data); static int cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len); static int cdreadsubchannel(struct cam_periph *periph, *************** *** 614,619 **** --- 626,633 ---- else softc->quirks = CD_Q_NONE; + softc->minimum_command_size = 6; + /* * We need to register the statistics structure for this device, * but we don't have the blocksize yet for it. So, we register *************** *** 1814,1819 **** --- 1828,1862 ---- xpt_release_ccb(done_ccb); } + static union cd_pages * + cdgetpage(struct cd_mode_params *mode_params) + { + union cd_pages *page; + + if (mode_params->cdb_size == 10) + page = (union cd_pages *)find_mode_page_10( + (struct scsi_mode_header_10 *)mode_params->mode_buf); + else + page = (union cd_pages *)find_mode_page_6( + (struct scsi_mode_header_6 *)mode_params->mode_buf); + + return (page); + } + + static int + cdgetpagesize(int page_num) + { + int i; + + for (i = 0; i < (sizeof(cd_page_size_table)/ + sizeof(cd_page_size_table[0])); i++) { + if (cd_page_size_table[i].page == page_num) + return (cd_page_size_table[i].page_size); + } + + return (-1); + } + static int cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { *************** *** 1846,1868 **** { struct ioc_play_track *args = (struct ioc_play_track *) addr; ! struct cd_mode_data *data; ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYTRACKS\n")); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.flags &= ~CD_PA_SOTC; ! data->page.audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); if (error) break; if (softc->quirks & CD_Q_BCD_TRACKS) { --- 1889,1915 ---- { struct ioc_play_track *args = (struct ioc_play_track *) addr; ! struct cd_mode_params params; ! union cd_pages *page; ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYTRACKS\n")); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.flags &= ~CD_PA_SOTC; ! page->audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); if (error) break; if (softc->quirks & CD_Q_BCD_TRACKS) { *************** *** 1880,1902 **** { struct ioc_play_msf *args = (struct ioc_play_msf *) addr; ! struct cd_mode_data *data; ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYMSF\n")); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.flags &= ~CD_PA_SOTC; ! data->page.audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); if (error) break; error = cdplaymsf(periph, --- 1927,1953 ---- { struct ioc_play_msf *args = (struct ioc_play_msf *) addr; ! struct cd_mode_params params; ! union cd_pages *page; ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYMSF\n")); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.flags &= ~CD_PA_SOTC; ! page->audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); if (error) break; error = cdplaymsf(periph, *************** *** 1912,1934 **** { struct ioc_play_blocks *args = (struct ioc_play_blocks *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYBLOCKS\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.flags &= ~CD_PA_SOTC; ! data->page.audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); if (error) break; error = cdplay(periph, args->blk, args->len); --- 1963,1989 ---- { struct ioc_play_blocks *args = (struct ioc_play_blocks *) addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCPLAYBLOCKS\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.flags &= ~CD_PA_SOTC; ! page->audio.flags |= CD_PA_IMMED; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); if (error) break; error = cdplay(periph, args->blk, args->len); *************** *** 2218,2413 **** break; case CDIOCSETPATCH: { ! struct ioc_patch *arg = (struct ioc_patch *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETPATCH\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = arg->patch[0]; ! data->page.audio.port[RIGHT_PORT].channels = arg->patch[1]; ! data->page.audio.port[2].channels = arg->patch[2]; ! data->page.audio.port[3].channels = arg->patch[3]; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCGETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCGETVOL\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } arg->vol[LEFT_PORT] = ! data->page.audio.port[LEFT_PORT].volume; arg->vol[RIGHT_PORT] = ! data->page.audio.port[RIGHT_PORT].volume; ! arg->vol[2] = data->page.audio.port[2].volume; ! arg->vol[3] = data->page.audio.port[3].volume; ! free(data, M_TEMP); } break; case CDIOCSETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETVOL\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = CHANNEL_0; ! data->page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT]; ! data->page.audio.port[RIGHT_PORT].channels = CHANNEL_1; ! data->page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT]; ! data->page.audio.port[2].volume = arg->vol[2]; ! data->page.audio.port[3].volume = arg->vol[3]; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETMONO: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMONO\n")); ! data = malloc(sizeof(struct cd_mode_data), ! M_TEMP, M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETSTEREO: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETSTEREO\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETMUTE: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMUTE\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = 0; ! data->page.audio.port[RIGHT_PORT].channels = 0; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETLEFT: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETLEFT\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = ! LEFT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = ! LEFT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCSETRIGHT: { ! struct cd_mode_data *data; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETRIGHT\n")); ! data = malloc(sizeof(struct cd_mode_data), M_TEMP, ! M_WAITOK); ! error = cdgetmode(periph, data, AUDIO_PAGE); if (error) { ! free(data, M_TEMP); break; } ! data->page.audio.port[LEFT_PORT].channels = ! RIGHT_CHANNEL; ! data->page.audio.port[RIGHT_PORT].channels = ! RIGHT_CHANNEL; ! data->page.audio.port[2].channels = 0; ! data->page.audio.port[3].channels = 0; ! error = cdsetmode(periph, data); ! free(data, M_TEMP); } break; case CDIOCRESUME: --- 2273,2498 ---- break; case CDIOCSETPATCH: { ! struct ioc_patch *arg = (struct ioc_patch *)addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETPATCH\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = arg->patch[0]; ! page->audio.port[RIGHT_PORT].channels = arg->patch[1]; ! page->audio.port[2].channels = arg->patch[2]; ! page->audio.port[3].channels = arg->patch[3]; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCGETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCGETVOL\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf= malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } + page = cdgetpage(¶ms); + arg->vol[LEFT_PORT] = ! page->audio.port[LEFT_PORT].volume; arg->vol[RIGHT_PORT] = ! page->audio.port[RIGHT_PORT].volume; ! arg->vol[2] = page->audio.port[2].volume; ! arg->vol[3] = page->audio.port[3].volume; ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETVOL: { struct ioc_vol *arg = (struct ioc_vol *) addr; ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETVOL\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = CHANNEL_0; ! page->audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT]; ! page->audio.port[RIGHT_PORT].channels = CHANNEL_1; ! page->audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT]; ! page->audio.port[2].volume = arg->vol[2]; ! page->audio.port[3].volume = arg->vol[3]; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETMONO: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMONO\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = LEFT_CHANNEL | RIGHT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETSTEREO: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETSTEREO\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETMUTE: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETMUTE\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(¶ms, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = 0; ! page->audio.port[RIGHT_PORT].channels = 0; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETLEFT: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETLEFT\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = LEFT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = LEFT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCSETRIGHT: { ! struct cd_mode_params params; ! union cd_pages *page; CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, ("trying to do CDIOCSETRIGHT\n")); ! params.alloc_len = sizeof(union cd_mode_data_6_10); ! params.mode_buf = malloc(params.alloc_len, M_TEMP, ! M_WAITOK | M_ZERO); ! ! error = cdgetmode(periph, ¶ms, AUDIO_PAGE); if (error) { ! free(params.mode_buf, M_TEMP); break; } ! page = cdgetpage(¶ms); ! ! page->audio.port[LEFT_PORT].channels = RIGHT_CHANNEL; ! page->audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL; ! page->audio.port[2].channels = 0; ! page->audio.port[3].channels = 0; ! error = cdsetmode(periph, ¶ms); ! free(params.mode_buf, M_TEMP); } break; case CDIOCRESUME: *************** *** 2648,2661 **** --- 2733,2897 ---- } static int + cd6byteworkaround(union ccb *ccb) + { + u_int8_t *cdb; + struct cam_periph *periph; + struct cd_softc *softc; + struct cd_mode_params *params; + int frozen; + + periph = xpt_path_periph(ccb->ccb_h.path); + softc = (struct cd_softc *)periph->softc; + + cdb = ccb->csio.cdb_io.cdb_bytes; + + if ((ccb->ccb_h.flags & CAM_CDB_POINTER) + || ((cdb[0] != MODE_SENSE_6) + && (cdb[0] != MODE_SELECT_6))) + return (0); + + /* + * Because there is no other convenient place to stash the overall + * cd_mode_params structure pointer, we have to grab it like this. + * This means that ALL MODE_SENSE and MODE_SELECT requests in the + * cd(4) driver MUST go through cdgetmode() and cdsetmode()! + */ + params = (struct cd_mode_params *)(ccb->csio.data_ptr - + __offsetof(struct cd_mode_params, mode_buf)); + + params->cdb_size = 10; + softc->minimum_command_size = 10; + xpt_print_path(ccb->ccb_h.path); + printf("MODE_SENSE(6)/MODE_SELECT(6) failed, increasing " + "minimum CDB size to 10 bytes\n"); + /* XXX KDM remove this */ + printf("CAM Status %#x\n", ccb->ccb_h.status); + printf("SCSI Status %#x\n", ccb->csio.scsi_status); + scsi_sense_print(&ccb->csio); + + if (cdb[0] == MODE_SENSE_6) { + struct scsi_mode_sense_10 ms10; + struct scsi_mode_sense_6 *ms6; + int len; + + ms6 = (struct scsi_mode_sense_6 *)cdb; + + bzero(&ms10, sizeof(ms10)); + ms10.opcode = MODE_SENSE_10; + ms10.byte2 = ms6->byte2; + ms10.page = ms6->page; + + /* + * 10 byte mode header, block descriptor, + * sizeof(union cd_pages) + */ + len = sizeof(struct cd_mode_data_10); + ccb->csio.dxfer_len = len; + + scsi_ulto2b(len, ms10.length); + ms10.control = ms6->control; + bcopy(&ms10, cdb, 10); + ccb->csio.cdb_len = 10; + } else { + struct scsi_mode_select_10 ms10; + struct scsi_mode_select_6 *ms6; + struct scsi_mode_header_6 *header6; + struct scsi_mode_header_10 *header10; + struct scsi_mode_page_header *page_header; + int blk_desc_len, page_num, page_size, len; + + ms6 = (struct scsi_mode_select_6 *)cdb; + + bzero(&ms10, sizeof(ms10)); + ms10.opcode = MODE_SELECT_10; + ms10.byte2 = ms6->byte2; + + header6 = (struct scsi_mode_header_6 *)params->mode_buf; + header10 = (struct scsi_mode_header_10 *)params->mode_buf; + + page_header = find_mode_page_6(header6); + page_num = page_header->page_code; + + blk_desc_len = header6->blk_desc_len; + + page_size = cdgetpagesize(page_num); + + if (page_size != (page_header->page_length + + sizeof(*page_header))) + page_size = page_header->page_length + + sizeof(*page_header); + + len = sizeof(*header10) + blk_desc_len + page_size; + + len = min(params->alloc_len, len); + + /* + * Since the 6 byte parameter header is shorter than the 10 + * byte parameter header, we need to copy the actual mode + * page data, and the block descriptor, if any, so things wind + * up in the right place. The regions will overlap, but + * bcopy() does the right thing. + */ + bcopy(params->mode_buf + sizeof(*header6), + params->mode_buf + sizeof(*header10), + len - sizeof(*header10)); + + /* Make sure these fields are set correctly. */ + scsi_ulto2b(0, header10->data_length); + header10->medium_type = 0; + scsi_ulto2b(blk_desc_len, header10->blk_desc_len); + + ccb->csio.dxfer_len = len; + + scsi_ulto2b(len, ms10.length); + ms10.control = ms6->control; + bcopy(&ms10, cdb, 10); + ccb->csio.cdb_len = 10; + } + + frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0; + ccb->ccb_h.status = CAM_REQUEUE_REQ; + xpt_action(ccb); + if (frozen) { + cam_release_devq(ccb->ccb_h.path, + /*relsim_flags*/0, + /*openings*/0, + /*timeout*/0, + /*getcount_only*/0); + } + + return (ERESTART); + } + + static int cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) { struct cd_softc *softc; struct cam_periph *periph; + int error; periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct cd_softc *)periph->softc; + error = 0; + + if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) + && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) + && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) + && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0) + && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) { + int sense_key, error_code, asc, ascq; + + scsi_extract_sense(&ccb->csio.sense_data, + &error_code, &sense_key, &asc, &ascq); + if (sense_key == SSD_KEY_ILLEGAL_REQUEST) + error = cd6byteworkaround(ccb); + } + + if (error == ERESTART) + return (error); + /* * XXX * Until we have a better way of doing pack validation, *************** *** 2764,2847 **** return(error); } ! static int ! cdgetmode(struct cam_periph *periph, struct cd_mode_data *data, u_int32_t page) { ! struct scsi_mode_sense_6 *scsi_cmd; ! struct ccb_scsiio *csio; union ccb *ccb; int error; ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; ! bzero(data, sizeof(*data)); ! cam_fill_csio(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* flags */ CAM_DIR_IN, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* data_ptr */ (u_int8_t *)data, ! /* dxfer_len */ sizeof(*data), ! /* sense_len */ SSD_FULL_SIZE, ! sizeof(struct scsi_mode_sense_6), ! /* timeout */ 50000); ! scsi_cmd = (struct scsi_mode_sense_6 *)&csio->cdb_io.cdb_bytes; ! bzero (scsi_cmd, sizeof(*scsi_cmd)); ! scsi_cmd->page = page; ! scsi_cmd->length = sizeof(*data) & 0xff; ! scsi_cmd->opcode = MODE_SENSE; error = cdrunccb(ccb, cderror, /*cam_flags*/0, /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO); xpt_release_ccb(ccb); return(error); } static int ! cdsetmode(struct cam_periph *periph, struct cd_mode_data *data) { ! struct scsi_mode_select_6 *scsi_cmd; ! struct ccb_scsiio *csio; union ccb *ccb; int error; ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; error = 0; ! cam_fill_csio(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* flags */ CAM_DIR_OUT, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* data_ptr */ (u_int8_t *)data, ! /* dxfer_len */ sizeof(*data), ! /* sense_len */ SSD_FULL_SIZE, ! sizeof(struct scsi_mode_select_6), ! /* timeout */ 50000); ! scsi_cmd = (struct scsi_mode_select_6 *)&csio->cdb_io.cdb_bytes; ! bzero(scsi_cmd, sizeof(*scsi_cmd)); ! scsi_cmd->opcode = MODE_SELECT; ! scsi_cmd->byte2 |= SMS_PF; ! scsi_cmd->length = sizeof(*data) & 0xff; ! data->header.data_length = 0; ! /* ! * SONY drives do not allow a mode select with a medium_type ! * value that has just been returned by a mode sense; use a ! * medium_type of 0 (Default) instead. ! */ ! data->header.medium_type = 0; error = cdrunccb(ccb, cderror, /*cam_flags*/0, /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); --- 3000,3177 ---- return(error); } ! /* ! * All MODE_SENSE requests in the cd(4) driver MUST go through this ! * routine. See comments in cd6byteworkaround() for details. ! */ static int ! cdgetmode(struct cam_periph *periph, struct cd_mode_params *data, ! u_int32_t page) { ! struct ccb_scsiio *csio; ! struct cd_softc *softc; union ccb *ccb; + int param_len; int error; + softc = (struct cd_softc *)periph->softc; + ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; ! data->cdb_size = softc->minimum_command_size; ! if (data->cdb_size < 10) ! param_len = sizeof(struct cd_mode_data); ! else ! param_len = sizeof(struct cd_mode_data_10); ! /* Don't say we've got more room than we actually allocated */ ! param_len = min(param_len, data->alloc_len); ! scsi_mode_sense_len(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* dbd */ 0, ! /* page_code */ SMS_PAGE_CTRL_CURRENT, ! /* page */ page, ! /* param_buf */ data->mode_buf, ! /* param_len */ param_len, ! /* minimum_cmd_size */ softc->minimum_command_size, ! /* sense_len */ SSD_FULL_SIZE, ! /* timeout */ 50000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, /*sense_flags*/SF_RETRY_UA|SF_RETRY_SELTO); xpt_release_ccb(ccb); + /* + * This is a bit of belt-and-suspenders checking, but if we run + * into a situation where the target sends back multiple block + * descriptors, we might not have enough space in the buffer to + * see the whole mode page. Better to return an error than + * potentially access memory beyond our malloced region. + */ + if (error == 0) { + u_int32_t data_len; + + if (data->cdb_size == 10) { + struct scsi_mode_header_10 *hdr10; + + hdr10 = (struct scsi_mode_header_10 *)data->mode_buf; + data_len = scsi_2btoul(hdr10->data_length); + data_len += sizeof(hdr10->data_length); + } else { + struct scsi_mode_header_6 *hdr6; + + hdr6 = (struct scsi_mode_header_6 *)data->mode_buf; + data_len = hdr6->data_length; + data_len += sizeof(hdr6->data_length); + } + + /* + * Complain if there is more mode data available than we + * allocated space for. This could potentially happen if + * we miscalculated the page length for some reason, if the + * drive returns multiple block descriptors, or if it sets + * the data length incorrectly. + */ + if (data_len > data->alloc_len) { + xpt_print_path(periph->path); + printf("allocated modepage %d length %d < returned " + "length %d\n", page, data->alloc_len, data_len); + + error = ENOSPC; + } + } return(error); } + /* + * All MODE_SELECT requests in the cd(4) driver MUST go through this + * routine. See comments in cd6byteworkaround() for details. + */ static int ! cdsetmode(struct cam_periph *periph, struct cd_mode_params *data) { ! struct ccb_scsiio *csio; ! struct cd_softc *softc; union ccb *ccb; + int cdb_size, param_len; int error; + softc = (struct cd_softc *)periph->softc; + ccb = cdgetccb(periph, /* priority */ 1); csio = &ccb->csio; error = 0; ! /* ! * If the data is formatted for the 10 byte version of the mode ! * select parameter list, we need to use the 10 byte CDB. ! * Otherwise, we use whatever the stored minimum command size. ! */ ! if (data->cdb_size == 10) ! cdb_size = data->cdb_size; ! else ! cdb_size = softc->minimum_command_size; ! if (cdb_size >= 10) { ! struct scsi_mode_header_10 *mode_header; ! u_int32_t data_len; ! mode_header = (struct scsi_mode_header_10 *)data->mode_buf; ! ! data_len = scsi_2btoul(mode_header->data_length); ! ! scsi_ulto2b(0, mode_header->data_length); ! /* ! * SONY drives do not allow a mode select with a medium_type ! * value that has just been returned by a mode sense; use a ! * medium_type of 0 (Default) instead. ! */ ! mode_header->medium_type = 0; ! ! /* ! * Pass back whatever the drive passed to us, plus the size ! * of the data length field. ! */ ! param_len = data_len + sizeof(mode_header->data_length); ! ! } else { ! struct scsi_mode_header_6 *mode_header; ! ! mode_header = (struct scsi_mode_header_6 *)data->mode_buf; ! ! param_len = mode_header->data_length + 1; ! ! mode_header->data_length = 0; ! /* ! * SONY drives do not allow a mode select with a medium_type ! * value that has just been returned by a mode sense; use a ! * medium_type of 0 (Default) instead. ! */ ! mode_header->medium_type = 0; ! } ! ! /* Don't say we've got more room than we actually allocated */ ! param_len = min(param_len, data->alloc_len); ! ! scsi_mode_select_len(csio, ! /* retries */ 1, ! /* cbfcnp */ cddone, ! /* tag_action */ MSG_SIMPLE_Q_TAG, ! /* scsi_page_fmt */ 1, ! /* save_pages */ 0, ! /* param_buf */ data->mode_buf, ! /* param_len */ param_len, ! /* minimum_cmd_size */ cdb_size, ! /* sense_len */ SSD_FULL_SIZE, ! /* timeout */ 50000); error = cdrunccb(ccb, cderror, /*cam_flags*/0, /*sense_flags*/SF_RETRY_UA | SF_RETRY_SELTO); *************** *** 2850,2856 **** return(error); } - static int cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len) --- 3180,3185 ---- ==== //depot/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_cd.h#1 - /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_cd.h ==== *** /tmp/tmp.1941.3 Sat Nov 9 23:41:11 2002 --- /usr/home/ken/perforce2/FreeBSD-ken-RELENG_4/src/sys/cam/scsi/scsi_cd.h Sat Nov 9 23:30:37 2002 *************** *** 645,682 **** u_int8_t length_0; /* Least significant */ }; ! union cd_pages { ! struct audio_page { ! u_int8_t page_code; ! #define CD_PAGE_CODE 0x3F ! #define AUDIO_PAGE 0x0e ! #define CD_PAGE_PS 0x80 ! u_int8_t param_len; ! u_int8_t flags; ! #define CD_PA_SOTC 0x02 ! #define CD_PA_IMMED 0x04 ! u_int8_t unused[2]; ! u_int8_t format_lba; ! #define CD_PA_FORMAT_LBA 0x0F ! #define CD_PA_APR_VALID 0x80 ! u_int8_t lb_per_sec[2]; ! struct port_control ! { ! u_int8_t channels; ! #define CHANNEL 0x0F ! #define CHANNEL_0 1 ! #define CHANNEL_1 2 ! #define CHANNEL_2 4 ! #define CHANNEL_3 8 ! #define LEFT_CHANNEL CHANNEL_0 ! #define RIGHT_CHANNEL CHANNEL_1 ! u_int8_t volume; ! } port[4]; ! #define LEFT_PORT 0 ! #define RIGHT_PORT 1 ! }audio; }; struct cd_mode_data --- 645,691 ---- u_int8_t length_0; /* Least significant */ }; ! struct cd_audio_page { ! u_int8_t page_code; ! #define CD_PAGE_CODE 0x3F ! #define AUDIO_PAGE 0x0e ! #define CD_PAGE_PS 0x80 ! u_int8_t param_len; ! u_int8_t flags; ! #define CD_PA_SOTC 0x02 ! #define CD_PA_IMMED 0x04 ! u_int8_t unused[2]; ! u_int8_t format_lba; ! #define CD_PA_FORMAT_LBA 0x0F ! #define CD_PA_APR_VALID 0x80 ! u_int8_t lb_per_sec[2]; ! struct port_control { ! u_int8_t channels; ! #define CHANNEL 0x0F ! #define CHANNEL_0 1 ! #define CHANNEL_1 2 ! #define CHANNEL_2 4 ! #define CHANNEL_3 8 ! #define LEFT_CHANNEL CHANNEL_0 ! #define RIGHT_CHANNEL CHANNEL_1 ! u_int8_t volume; ! } port[4]; ! #define LEFT_PORT 0 ! #define RIGHT_PORT 1 ! }; ! ! union cd_pages ! { ! struct cd_audio_page audio; ! }; ! ! struct cd_mode_data_10 ! { ! struct scsi_mode_header_10 header; ! struct scsi_mode_blk_desc blk_desc; ! union cd_pages page; }; struct cd_mode_data *************** *** 684,689 **** --- 693,719 ---- struct scsi_mode_header_6 header; struct scsi_mode_blk_desc blk_desc; union cd_pages page; + }; + + union cd_mode_data_6_10 + { + struct cd_mode_data mode_data_6; + struct cd_mode_data_10 mode_data_10; + }; + + #if 0 + struct cd_mode_params + { + int cdb_size; + union cd_mode_data_6_10 mode_data; + }; + #endif + + struct cd_mode_params + { + int cdb_size; + int alloc_len; + u_int8_t *mode_buf; }; __BEGIN_DECLS --ikeVEW9yuYc//A+q-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Mon Nov 11 7:35:41 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4434E37B401 for ; Mon, 11 Nov 2002 07:35:40 -0800 (PST) Received: from CPE0004761ac738-CM00109515bc65.cpe.net.cable.rogers.com (CPE0004761ac738-CM00109515bc65.cpe.net.cable.rogers.com [24.103.39.131]) by mx1.FreeBSD.org (Postfix) with SMTP id 3231543E4A for ; Mon, 11 Nov 2002 07:35:39 -0800 (PST) (envelope-from miro@cybershade.us) Received: (qmail 55943 invoked from network); 11 Nov 2002 15:35:52 -0000 Received: from unknown (HELO vsivyoung) (66.46.21.253) by cpe0004761ac738-cm00109515bc65.cpe.net.cable.rogers.com with SMTP; 11 Nov 2002 15:35:52 -0000 Message-ID: <00ec01c28997$fc2511b0$c801a8c0@vsivyoung> From: "Miroslav Pendev" To: "SCSI FreeBSD" Subject: SCSI tape error - End-of-data detected Date: Mon, 11 Nov 2002 10:35:36 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1106 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Hi, I just did upgrade of our SCSI DDS3 tape archiver from HP12GB to HP 20GB(40 w comppresion). From dmesg: sa0 at ahc0 bus 0 target 4 lun 0 sa0: Removable Sequential Access SCSI-2 device sa0: 20.000MB/s transfers (20.000MHz, offset 15) I have two full backups without any errors but this morning I've got the following from the /kernel (sa0:ahc0:0:4:0): WRITE FILEMARKS. CDB: 10 0 0 0 1 0 (sa0:ahc0:0:4:0): BLANK CHECK req sz: 0 (decimal) asc:0,5 (sa0:ahc0:0:4:0): End-of-data detected (sa0:ahc0:0:4:0): failed to write terminating filemark(s) I am not sure what's wrong with the tape this time? What does End-of-data detected means? The backup script didn't return any errors, well at least tar c /path/to/backup didn't return error. Any ideas are welcome! Thanks in advance! Miro To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Mon Nov 11 11: 2:12 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5A85237B404 for ; Mon, 11 Nov 2002 11:02:11 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3536543E77 for ; Mon, 11 Nov 2002 11:02:06 -0800 (PST) (envelope-from owner-bugmaster@freebsd.org) Received: from freefall.freebsd.org (peter@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id gABJ26x3076292 for ; Mon, 11 Nov 2002 11:02:06 -0800 (PST) (envelope-from owner-bugmaster@freebsd.org) Received: (from peter@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id gABJ26GJ076280 for scsi@freebsd.org; Mon, 11 Nov 2002 11:02:06 -0800 (PST) Date: Mon, 11 Nov 2002 11:02:06 -0800 (PST) Message-Id: <200211111902.gABJ26GJ076280@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: peter set sender to owner-bugmaster@freebsd.org using -f From: FreeBSD bugmaster To: scsi@FreeBSD.org Subject: Current problem reports assigned to you Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Current FreeBSD problem reports Critical problems S Submitted Tracker Resp. Description ------------------------------------------------------------------------------- f [2002/02/18] kern/35082 scsi IBM Intellistation will not reboot with S 1 problem total. Serious problems Non-critical problems S Submitted Tracker Resp. Description ------------------------------------------------------------------------------- f [1999/12/21] kern/15608 scsi acd0 / cd0 give inconsistent errors on em 1 problem total. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Mon Nov 11 14: 4:54 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D3DD837B401 for ; Mon, 11 Nov 2002 14:04:52 -0800 (PST) Received: from rootlabs.com (root.org [67.118.192.226]) by mx1.FreeBSD.org (Postfix) with SMTP id 0ABB643E42 for ; Mon, 11 Nov 2002 14:04:48 -0800 (PST) (envelope-from nate@rootlabs.com) Received: (qmail 34009 invoked by uid 1000); 11 Nov 2002 22:04:48 -0000 Date: Mon, 11 Nov 2002 14:04:48 -0800 (PST) From: Nate Lawson To: Miroslav Pendev Cc: SCSI FreeBSD Subject: Re: SCSI tape error - End-of-data detected In-Reply-To: <00ec01c28997$fc2511b0$c801a8c0@vsivyoung> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org On Mon, 11 Nov 2002, Miroslav Pendev wrote: > Hi, > > I just did upgrade of our SCSI DDS3 tape archiver from > HP12GB to HP 20GB(40 w comppresion). > > From dmesg: > sa0 at ahc0 bus 0 target 4 lun 0 > sa0: Removable Sequential Access SCSI-2 device > sa0: 20.000MB/s transfers (20.000MHz, offset 15) > > I have two full backups without any errors but this morning > I've got the following from the /kernel > > (sa0:ahc0:0:4:0): WRITE FILEMARKS. CDB: 10 0 0 0 1 0 > (sa0:ahc0:0:4:0): BLANK CHECK req sz: 0 (decimal) asc:0,5 > (sa0:ahc0:0:4:0): End-of-data detected > (sa0:ahc0:0:4:0): failed to write terminating filemark(s) > > I am not sure what's wrong with the tape this time? > What does End-of-data detected means? > > The backup script didn't return any errors, well at least > tar c /path/to/backup didn't return error. > > Any ideas are welcome! You had two full backups with teh new drive without any errors? And all you changed was the tape to get an error? Perhaps it's a bad tape? See if you can get a reproduceable error and then please report. -Nate To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Mon Nov 11 14:29:49 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4970937B401 for ; Mon, 11 Nov 2002 14:29:48 -0800 (PST) Received: from panzer.kdm.org (panzer.kdm.org [216.160.178.169]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8497E43E75 for ; Mon, 11 Nov 2002 14:29:47 -0800 (PST) (envelope-from ken@panzer.kdm.org) Received: from panzer.kdm.org (localhost [127.0.0.1]) by panzer.kdm.org (8.12.5/8.12.5) with ESMTP id gABMTkKD088252; Mon, 11 Nov 2002 15:29:46 -0700 (MST) (envelope-from ken@panzer.kdm.org) Received: (from ken@localhost) by panzer.kdm.org (8.12.5/8.12.5/Submit) id gABMTjam088251; Mon, 11 Nov 2002 15:29:45 -0700 (MST) (envelope-from ken) Date: Mon, 11 Nov 2002 15:29:45 -0700 From: "Kenneth D. Merry" To: Kuritex Cc: freebsd-scsi@FreeBSD.ORG Subject: Re: FreeBSD on the HP's tc2100/SCSI-version Message-ID: <20021111152945.A88208@panzer.kdm.org> References: <1533795648.20021111093454@mail.i.com.ua> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <1533795648.20021111093454@mail.i.com.ua>; from kuritex@mail.i.com.ua on Mon, Nov 11, 2002 at 09:34:54AM +0200 Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org On Mon, Nov 11, 2002 at 09:34:54 +0200, Kuritex wrote: > Hello all subscribers, > > Gonna upgrade our corporative mail-server (common PII running FreeBSD, > of course) up to the brand hardware, namely HP's tc2100 server model > (1.3 GHz PIII, SCSI-version shipping single-channel SCSI-controller). > So the following question appears: is there any hidden rocks in the > FreeBSD 4.5 installation on this HP model (as far as 'Flexibility' > section in tc2100 data sheet doesn't list FreeBSD as a supported OS) > and what are the possible troubles I may clash during installation? > Anyway, has anybody here experienced installing FreeBSD distributive > on tc2100? It'll probably work fine, but we'd need to know what kind of SCSI controller they're using in order to say for sure whether it'll work. Chances are, though, it's either an Adaptec or LSI SCSI controller, so you should be fine. Ken -- Kenneth Merry ken@kdm.org To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 2:17:14 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EDBB737B401 for ; Tue, 12 Nov 2002 02:17:10 -0800 (PST) Received: from kashmir.etowns.net (dsl-65-184-96-65.telocity.com [65.184.96.65]) by mx1.FreeBSD.org (Postfix) with ESMTP id 10C0C43E4A for ; Tue, 12 Nov 2002 02:17:05 -0800 (PST) (envelope-from somebody@kashmir.etowns.net) Received: from kashmir.etowns.net (kashmir.etowns.net [65.184.96.65]) by kashmir.etowns.net (8.12.6/8.12.6) with ESMTP id gACAGwhF012643; Tue, 12 Nov 2002 02:16:59 -0800 (PST) (envelope-from somebody@kashmir.etowns.net) Received: (from somebody@localhost) by kashmir.etowns.net (8.12.6/8.12.6/Submit) id gACAGuWK012642; Tue, 12 Nov 2002 02:16:56 -0800 (PST) Date: Tue, 12 Nov 2002 02:16:56 -0800 From: ANYBODY To: David Schultz Cc: scsi@freebsd.org Subject: Re: adaptec scsi - seagate da -- current Message-ID: <20021112101656.GA12579@kashmir.etowns.net> References: <20021030095416.GA1840@hurd1.kashmir.etowns.net> <376290000.1035997229@aslan.btc.adaptec.com> <20021110081757.GA961@HAL9000.homeunix.com> <20021111094918.GA5702@HAL9000.homeunix.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20021111094918.GA5702@HAL9000.homeunix.com> User-Agent: Mutt/1.4i Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org hunh my problem seems to be pretty similar however it was happening because of extremely heavy tag depth ( > 200 ). after automatic adjustment it used to be around 63 so I manually forced it to be reduced to 60 at bootup by adding a command in /etc/rc.local camcontrol tags da0 -N 60 looks like around <= 16 would be a good number for your da0. MAKE SURE YOU HAVE READ MY PREV. THREAD COMPLETELY. exactly why this happens even though my hardware is not borderline.... is something that I havent yet figured.... tag depth is the amount of concurrency. It does not have to be over 200 for good performance. Matter of fact even 8,16 etc give a very reasonable performance. also make sure the scsi bus is properly terminated on ( and only on ) the 2 ends. you can use physical terminators at the 2 ends of the bus or have the last devices ( according to physical wiring ) set to use the internal terminators(if they have them). Its the same. Usually card is on 1 end and the drive on the other if all drives are internal and no external scsi device. Most cards have the option of enabling the terminator through the bios : make sure it is enabled (only if in your condition it is the last device on 1 end.). most cards and devices also support supplying power to a terminator outside (if you have an external terminator). (power to the bus) having a couple of devices supplying power to the bus if you have physical terms is ok. if no physical terminators make sure the internal terms are supplied with power. jumpers on the hard drives. look into the drive manuals. Seagate maintains extensive manuals on their website. seagate.com look around for disk encyclopaedia. I am not sure if quantum is a seagate product. Also people have reported that low level formatting some times helps -- if you can do it either from scsi bios or from freebsd...... I lost patience and dont think needed to either. Some scsi bios settings also contain some option for tag depths... I have seen atleast 1 if I remember correctly which is set to low usually. Hope this helps Let me know Best regards, Saurabh Gupta On Mon, Nov 11, 2002 at 01:49:18AM -0800, David Schultz wrote: > Thus spake David Schultz : > > I'm running into the same problems on a very light I/O load > > (running /usr/bin/less on certain files triggers it). There's > > also a timeout every time at bootup. I have included my dmesg > > below. > [...] > > Here's some additional information: > > # camcontrol inquiry da0 > pass0: Fixed Direct Access SCSI-2 device > pass0: Serial Number PCB=2011303002 ; HDA=184715611932 > pass0: 20.000MB/s transfers (20.000MHz, offset 15), Tagged Queueing Enabled > # camcontrol tags da0 -v > (pass0:ahc0:0:0:0): dev_openings 24 > (pass0:ahc0:0:0:0): dev_active 0 > (pass0:ahc0:0:0:0): devq_openings 24 > (pass0:ahc0:0:0:0): devq_queued 0 > (pass0:ahc0:0:0:0): held 0 > (pass0:ahc0:0:0:0): mintags 24 > (pass0:ahc0:0:0:0): maxtags 32 > > # camcontrol inquiry da1 > pass1: Fixed Direct Access SCSI-2 device > pass1: Serial Number 174716034271 > pass1: 20.000MB/s transfers (20.000MHz, offset 15), Tagged Queueing Enabled > # camcontrol tags da1 -v > (pass1:ahc0:0:1:0): dev_openings 253 > (pass1:ahc0:0:1:0): dev_active 0 > (pass1:ahc0:0:1:0): devq_openings 253 > (pass1:ahc0:0:1:0): devq_queued 0 > (pass1:ahc0:0:1:0): held 0 > (pass1:ahc0:0:1:0): mintags 2 > (pass1:ahc0:0:1:0): maxtags 255 > > It seems like da0 is the problem device. Just after it times out > now and then, camcontrol shows things like: > > # camcontrol tags da0 -v > (pass0:ahc0:0:0:0): dev_openings 22 > (pass0:ahc0:0:0:0): dev_active 2 > (pass0:ahc0:0:0:0): devq_openings 22 > (pass0:ahc0:0:0:0): devq_queued 0 > (pass0:ahc0:0:0:0): held 0 > (pass0:ahc0:0:0:0): mintags 24 > (pass0:ahc0:0:0:0): maxtags 32 > > # camcontrol tags da0 -v > (pass0:ahc0:0:0:0): dev_openings 16 > (pass0:ahc0:0:0:0): dev_active 8 > (pass0:ahc0:0:0:0): devq_openings 16 > (pass0:ahc0:0:0:0): devq_queued 0 > (pass0:ahc0:0:0:0): held 0 > (pass0:ahc0:0:0:0): mintags 24 > (pass0:ahc0:0:0:0): maxtags 32 > > It seems like da1 is fine, but then again I use that drive less > heavily. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 2:53:53 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9BF6137B401 for ; Tue, 12 Nov 2002 02:53:52 -0800 (PST) Received: from gw.uic.ru (gw.uic.ru [62.102.149.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id C88E543E6E for ; Tue, 12 Nov 2002 02:53:48 -0800 (PST) (envelope-from vav@papillon.ru) Received: from papillon.ru (uucp@localhost) by gw.uic.ru (8.11.6/linuxconf) with UUCP id gACAriF03846 for freebsd-scsi@freebsd.org; Tue, 12 Nov 2002 15:53:44 +0500 Received: from vav by papillon.ru with SMTP id PAA24886; (8.7.5/vak/1.9) Tue, 12 Nov 2002 15:52:17 +0500 Message-ID: <00b901c28a39$366e9160$a615a8c0@papillon.ru> From: "Andrey Valik" To: Subject: transmission speed Date: Tue, 12 Nov 2002 15:49:35 +0500 MIME-Version: 1.0 Content-Type: text/plain; charset="x-user-defined" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4522.1200 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 FL-Build: Fidolook Express 2001 UIExt. BuildID: 3BC00FAD (7/10/2001 14:17:49). Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Hello! I have a SCSI target mode driver that emulate scanner, but transmission speed is 20Mb/sec. Both SCSI cards is Adaptec 19160. What I must do to speedup ? Thanks in advance. Andrey Valik. E-mail: vav@papillon.ru To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 10:56:54 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5501137B401 for ; Tue, 12 Nov 2002 10:56:53 -0800 (PST) Received: from rootlabs.com (root.org [67.118.192.226]) by mx1.FreeBSD.org (Postfix) with SMTP id 85D6043E4A for ; Tue, 12 Nov 2002 10:56:52 -0800 (PST) (envelope-from nate@rootlabs.com) Received: (qmail 36468 invoked by uid 1000); 12 Nov 2002 18:56:52 -0000 Date: Tue, 12 Nov 2002 10:56:52 -0800 (PST) From: Nate Lawson To: Andrey Valik Cc: freebsd-scsi@freebsd.org Subject: Re: transmission speed In-Reply-To: <00b901c28a39$366e9160$a615a8c0@papillon.ru> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org On Tue, 12 Nov 2002, Andrey Valik wrote: > Hello! > > I have a SCSI target mode driver that emulate scanner, but transmission > speed is 20Mb/sec. > Both SCSI cards is Adaptec 19160. What I must do to speedup ? Are you using the freebsd target driver, both usermode and kernel driver? (i.e. sys/cam/scsi_target.c and /usr/share/examples/scsi_target) If so, it only advertises it is capable of async transfers, so set SYNC and WIDE16 in the inquiry response. -Nate To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 11:51:29 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 34C3337B401 for ; Tue, 12 Nov 2002 11:51:28 -0800 (PST) Received: from sax.sax.de (sax.sax.de [193.175.26.33]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2310843E4A for ; Tue, 12 Nov 2002 11:51:26 -0800 (PST) (envelope-from j@uriah.heep.sax.de) Received: (from uucp@localhost) by sax.sax.de (8.9.3/8.9.3) with UUCP id UAA21648; Tue, 12 Nov 2002 20:50:05 +0100 (CET) Received: from uriah.heep.sax.de (localhost.heep.sax.de [127.0.0.1]) by uriah.heep.sax.de (8.12.5/8.12.5) with ESMTP id gACJmXWc030108; Tue, 12 Nov 2002 20:48:34 +0100 (MET) (envelope-from j@uriah.heep.sax.de) Received: (from j@localhost) by uriah.heep.sax.de (8.12.5/8.12.5/Submit) id gACJmXFc030107; Tue, 12 Nov 2002 20:48:33 +0100 (MET) (envelope-from j) Date: Tue, 12 Nov 2002 20:48:33 +0100 (MET) Message-Id: <200211121948.gACJmXFc030107@uriah.heep.sax.de> Mime-Version: 1.0 X-Newsreader: knews 1.0b.1 Reply-To: joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch) Organization: Private BSD site, Dresden X-Phone: +49-351-2012 669 X-PGP-Fingerprint: DC 47 E6 E4 FF A6 E9 8F 93 21 E0 7D F9 12 D6 4E References: <00ec01c28997$fc2511b0$c801a8c0@vsivyoung> From: j@uriah.heep.sax.de (Joerg Wunsch) Subject: Re: SCSI tape error - End-of-data detected X-Original-Newsgroups: local.freebsd.scsi To: freebsd-scsi@freebsd.org Cc: "Miroslav Pendev" Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org "Miroslav Pendev" wrote: > (sa0:ahc0:0:4:0): WRITE FILEMARKS. CDB: 10 0 0 0 1 0 > (sa0:ahc0:0:4:0): BLANK CHECK req sz: 0 (decimal) asc:0,5 > (sa0:ahc0:0:4:0): End-of-data detected > (sa0:ahc0:0:4:0): failed to write terminating filemark(s) I can't seem to find anything in the standard that warrants a blank check during a write filemarks. IMHO, it doesn't have much sense either, a write operation should never complain about a blank medium. Please obtain the SCSI reference manual for your drive, and see what they're writing about the write filemarks command. -- cheers, J"org .-.-. --... ...-- -.. . DL8DTL http://www.sax.de/~joerg/ NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 14:46: 3 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EF38737B401 for ; Tue, 12 Nov 2002 14:46:02 -0800 (PST) Received: from boromir.vpop.net (dns1.vpop.net [207.178.248.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id A81FE43E7B for ; Tue, 12 Nov 2002 14:46:02 -0800 (PST) (envelope-from mreimer@vpop.net) Received: from vpop.net (bilbo.vpop.net [65.103.33.41]) by boromir.vpop.net (Postfix) with ESMTP id B758C3A5E13; Tue, 12 Nov 2002 14:45:49 -0800 (PST) Message-ID: <3DD184FD.70003@vpop.net> Date: Tue, 12 Nov 2002 16:47:25 -0600 From: Matthew Reimer Organization: VPOP Technologies, Inc. User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.2b) Gecko/20021023 X-Accept-Language: en-us, en MIME-Version: 1.0 To: scsi@freebsd.org Subject: SOLVED: Re: raidutil/dpteng References: In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org FYI, it turns out that there weren't enough SysV semaphores available for raidutil and friends to run. Freeing some up fixed it. Increasing the maximum number of semaphores (kern.ipc.semmns) in /boot/loader.conf is a better long-term fix. Matt To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 20:20:58 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2F6A637B401 for ; Tue, 12 Nov 2002 20:20:57 -0800 (PST) Received: from gw.uic.ru (gw.uic.ru [62.102.149.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id ED0E843E4A for ; Tue, 12 Nov 2002 20:20:53 -0800 (PST) (envelope-from vav@papillon.ru) Received: from papillon.ru (uucp@localhost) by gw.uic.ru (8.11.6/linuxconf) with UUCP id gAD4KJG02948; Wed, 13 Nov 2002 09:20:19 +0500 Received: from papillon.ru by papillon.ru with ESMTP id JAA07571; (8.7.5/vak/1.9) Wed, 13 Nov 2002 09:17:00 +0500 Message-ID: <3DD1D22D.2E1B6120@papillon.ru> Date: Wed, 13 Nov 2002 09:16:45 +0500 From: Andrey Valik Organization: Papillon Systems Ltd. X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.18-6mdk i686) X-Accept-Language: ru, en MIME-Version: 1.0 To: Nate Lawson Cc: freebsd-scsi@freebsd.org Subject: Re: transmission speed References: Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Hello ! Nate Lawson wrote: > > On Tue, 12 Nov 2002, Andrey Valik wrote: > > Hello! > > > > I have a SCSI target mode driver that emulate scanner, but transmission > > speed is 20Mb/sec. > > Both SCSI cards is Adaptec 19160. What I must do to speedup ? > > Are you using the freebsd target driver, both usermode and kernel > driver? (i.e. sys/cam/scsi_target.c and /usr/share/examples/scsi_target) Yes, modificated by myself version from FreeBSD 4.5. scsi_target.c version 1.22.2.6 2001/03/05. > > If so, it only advertises it is capable of async transfers, so set SYNC > and WIDE16 in the inquiry response. I maked this before, but in this case I have 20Mb/s. I think, that I will need to write scsi negotiation, or may be it's already writed in the next versions of scsi_target ? Thanks in advance. -- Andrey V. Valik Papillon Systems. Mailto:vav@papillon.ru To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Tue Nov 12 22:57:13 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 60F0D37B406 for ; Tue, 12 Nov 2002 22:57:12 -0800 (PST) Received: from rootlabs.com (root.org [67.118.192.226]) by mx1.FreeBSD.org (Postfix) with SMTP id 9AD8A43E7B for ; Tue, 12 Nov 2002 22:57:08 -0800 (PST) (envelope-from nate@rootlabs.com) Received: (qmail 38201 invoked by uid 1000); 13 Nov 2002 06:57:10 -0000 Date: Tue, 12 Nov 2002 22:57:10 -0800 (PST) From: Nate Lawson To: Andrey Valik Cc: freebsd-scsi@freebsd.org Subject: Re: transmission speed In-Reply-To: <3DD1D22D.2E1B6120@papillon.ru> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org On Wed, 13 Nov 2002, Andrey Valik wrote: > Nate Lawson wrote: > > > > On Tue, 12 Nov 2002, Andrey Valik wrote: > > > Hello! > > > > > > I have a SCSI target mode driver that emulate scanner, but transmission > > > speed is 20Mb/sec. > > > Both SCSI cards is Adaptec 19160. What I must do to speedup ? > > > > Are you using the freebsd target driver, both usermode and kernel > > driver? (i.e. sys/cam/scsi_target.c and /usr/share/examples/scsi_target) > > Yes, modificated by myself version from FreeBSD 4.5. > scsi_target.c version 1.22.2.6 2001/03/05. So when you do a rescan, you get a device of type "FreeBSD TM-PT"? > > If so, it only advertises it is capable of async transfers, so set SYNC > > and WIDE16 in the inquiry response. > > I maked this before, but in this case I have 20Mb/s. I think, that I will need to write scsi > negotiation, or may be > it's already writed in the next versions of scsi_target ? If you modify /sys/cam/scsi/scsi_target.c where it allocates inquiry data to announce sync + wide16 (see the SCSI specs at t10.org), the ahc(4) driver should perform the appropriate negotiation for you at the initiatior's request. -Nate To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Wed Nov 13 0:41: 5 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5A52D37B401 for ; Wed, 13 Nov 2002 00:41:03 -0800 (PST) Received: from gw.uic.ru (gw.uic.ru [62.102.149.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0271D43E77 for ; Wed, 13 Nov 2002 00:41:01 -0800 (PST) (envelope-from vav@papillon.ru) Received: from papillon.ru (uucp@localhost) by gw.uic.ru (8.11.6/linuxconf) with UUCP id gAD8eLr11994; Wed, 13 Nov 2002 13:40:21 +0500 Received: from papillon.ru by papillon.ru with ESMTP id NAA12168; (8.7.5/vak/1.9) Wed, 13 Nov 2002 13:38:51 +0500 Message-ID: <3DD20F8A.E594AACE@papillon.ru> Date: Wed, 13 Nov 2002 13:38:34 +0500 From: Andrey Valik Organization: Papillon Systems Ltd. X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.18-6mdk i686) X-Accept-Language: ru, en MIME-Version: 1.0 To: Nate Lawson Cc: freebsd-scsi@freebsd.org Subject: Re: transmission speed References: Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Nate Lawson wrote: > > On Wed, 13 Nov 2002, Andrey Valik wrote: > > Nate Lawson wrote: > > > > > > On Tue, 12 Nov 2002, Andrey Valik wrote: > > > > Hello! > > > > > > > > I have a SCSI target mode driver that emulate scanner, but transmission > > > > speed is 20Mb/sec. > > > > Both SCSI cards is Adaptec 19160. What I must do to speedup ? > > > > > > Are you using the freebsd target driver, both usermode and kernel > > > driver? (i.e. sys/cam/scsi_target.c and /usr/share/examples/scsi_target) > > > > Yes, modificated by myself version from FreeBSD 4.5. > > scsi_target.c version 1.22.2.6 2001/03/05. > > So when you do a rescan, you get a device of type "FreeBSD TM-PT"? > It was before modification. I need emulate scanner AGFA, intialization of inq_data: softc->inq_data->device = T_SCANNER | (SID_QUAL_LU_CONNECTED << 5); softc->inq_data->version = 2; softc->inq_data->response_format = 2; /* SCSI2 Inquiry Format */ softc->inq_data->additional_length = 0x5B; strncpy(softc->inq_data->vendor, "AGFA ", SID_VENDOR_SIZE); strncpy(softc->inq_data->product, "DUOSCAN T1200 ", SID_PRODUCT_SIZE); strncpy(softc->inq_data->revision, "1.30 ", SID_REVISION_SIZE); softc->inq_data->flags &= ~(PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32|PI_TAG_ABLE); softc->inq_data->flags |= (cpi->hba_inquiry & (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32|PI_TAG_ABLE)); The second PC is windows and linux - the same speed 20Mb/s. > > > If so, it only advertises it is capable of async transfers, so set SYNC > > > and WIDE16 in the inquiry response. > > > > I maked this before, but in this case I have 20Mb/s. I think, that I will need to write scsi > > negotiation, or may be > > it's already writed in the next versions of scsi_target ? > > If you modify /sys/cam/scsi/scsi_target.c where it allocates inquiry data > to announce sync + wide16 (see the SCSI specs at t10.org), the > ahc(4) driver should perform the appropriate negotiation for you at the > initiatior's request. wide16 - PI_WIDE_16 sync - ???? (May be problem in this place ?) -- Andrey V. Valik Papillon Systems Mailto:vav@papillon.ru To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Wed Nov 13 11:32:31 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D365E37B401 for ; Wed, 13 Nov 2002 11:32:30 -0800 (PST) Received: from rootlabs.com (root.org [67.118.192.226]) by mx1.FreeBSD.org (Postfix) with SMTP id 3E01243E7B for ; Wed, 13 Nov 2002 11:32:30 -0800 (PST) (envelope-from nate@rootlabs.com) Received: (qmail 40285 invoked by uid 1000); 13 Nov 2002 19:32:30 -0000 Date: Wed, 13 Nov 2002 11:32:30 -0800 (PST) From: Nate Lawson To: Andrey Valik Cc: freebsd-scsi@freebsd.org Subject: Re: transmission speed In-Reply-To: <3DD20F8A.E594AACE@papillon.ru> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org I've given you all the information you need. Please see the INQUIRY response section of SPC doc on t10.org or just wait until the new targ(4) is committed. Its usermode offers command line flags for the various inquiry responses. -Nate To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Wed Nov 13 19:40:47 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 612B737B401 for ; Wed, 13 Nov 2002 19:40:46 -0800 (PST) Received: from gw.uic.ru (gw.uic.ru [62.102.149.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id D8D7843E4A for ; Wed, 13 Nov 2002 19:40:43 -0800 (PST) (envelope-from vav@papillon.ru) Received: from papillon.ru (uucp@localhost) by gw.uic.ru (8.11.6/linuxconf) with UUCP id gAE3e3p10475; Thu, 14 Nov 2002 08:40:03 +0500 Received: from vav by papillon.ru with SMTP id IAA29479; (8.7.5/vak/1.9) Thu, 14 Nov 2002 08:39:36 +0500 Message-ID: <000c01c28b8f$64b96110$a615a8c0@papillon.ru> From: "Andrey Valik" To: "Nate Lawson" Cc: References: Subject: Re: transmission speed Date: Thu, 14 Nov 2002 08:39:10 +0500 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4522.1200 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Ok, sank you very much. Andrey Valik, Papillon Systems. mailto:vav@papillon.ru ----- Original Message ----- From: "Nate Lawson" To: "Andrey Valik" Cc: Sent: Thursday, November 14, 2002 12:32 AM Subject: Re: transmission speed > I've given you all the information you need. Please see the INQUIRY > response section of SPC doc on t10.org or just wait until the new > targ(4) is committed. Its usermode offers command line flags for the > various inquiry responses. > > -Nate > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Thu Nov 14 5:36:52 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D362A37B401 for ; Thu, 14 Nov 2002 05:36:50 -0800 (PST) Received: from ida.interface-business.de (ida.interface-business.de [193.101.57.9]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9AE1643E8A for ; Thu, 14 Nov 2002 05:36:49 -0800 (PST) (envelope-from j@ida.interface-business.de) Received: from ida.interface-business.de (localhost [127.0.0.1]) by ida.interface-business.de (8.12.5/8.12.5/ifb) with ESMTP id gAEDaic6010617 for ; Thu, 14 Nov 2002 14:36:44 +0100 (MET) (envelope-from j@ida.interface-business.de) Received: (from j@localhost) by ida.interface-business.de (8.12.5/8.12.5/Submit) id gAEDahKp010616 for scsi@freebsd.org; Thu, 14 Nov 2002 14:36:43 +0100 (MET) (envelope-from j) Date: Thu, 14 Nov 2002 14:36:42 +0100 From: Joerg Wunsch To: scsi@freebsd.org Subject: How to recover an invalidated device? Message-ID: <20021114143642.I8753@ida.interface-business.de> Reply-To: Joerg Wunsch Mail-Followup-To: scsi@freebsd.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i X-Phone: +49-351-31809-14 X-PGP-Fingerprint: DC 47 E6 E4 FF A6 E9 8F 93 21 E0 7D F9 12 D6 4E Organization: interface systems GmbH, Dresden Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org After pulling a disk in a mirrored configuration, i get the following (expected) errors: Nov 14 14:15:32 xcd6 /kernel: (da1:ahc0:0:6:0): Invalidating pack Vinum disconfigures the affected plexes. So far, so good. However, after replugging the drive, how do i get it alive again? All camcontrol commands work pretty well: xcd6# camcontrol inquiry da1 pass1: Fixed Direct Access SCSI-3 device pass1: Serial Number 3FD1EYLX00002307C07Y pass1: 160.000MB/s transfers (80.000MHz, offset 63, 16bit), Tagged Queueing Enabled xcd6# camcontrol neg da1 Current Parameters: (pass1:ahc0:0:6:0): sync parameter: 9 (pass1:ahc0:0:6:0): frequency: 80.000MHz (pass1:ahc0:0:6:0): offset: 63 (pass1:ahc0:0:6:0): bus width: 16 bits (pass1:ahc0:0:6:0): disconnection is enabled (pass1:ahc0:0:6:0): tagged queueing is enabled Yet, an attempt to access the device fails: xcd6# hd /dev/da1h hd: /dev/da1h: Device not configured Right now, the only way i know to get out of this dilemma is to unplug the drive again, "camcontrol rescan" so it will be removed completely, replug it, "camcontrol rescan" so it's known again. I think this is not quite optimal... Isn't there another way to get the da driver back to live? IMHO there should be one. -- J"org Wunsch Unix support engineer joerg_wunsch@interface-systems.de http://www.interface-systems.de/~j/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Thu Nov 14 7:51: 7 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A55EC37B401 for ; Thu, 14 Nov 2002 07:51:06 -0800 (PST) Received: from sasami.jurai.net (sasami.jurai.net [66.92.160.223]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0896A43E4A for ; Thu, 14 Nov 2002 07:51:06 -0800 (PST) (envelope-from winter@jurai.net) Received: from sasami.jurai.net (sasami.jurai.net [66.92.160.223]) by sasami.jurai.net (8.12.6/8.12.5) with ESMTP id gAEFp46D093468; Thu, 14 Nov 2002 10:51:04 -0500 (EST) (envelope-from winter@jurai.net) Date: Thu, 14 Nov 2002 10:51:04 -0500 (EST) From: "Matthew N. Dodd" To: Joerg Wunsch Cc: scsi@FreeBSD.ORG Subject: Re: How to recover an invalidated device? In-Reply-To: <20021114143642.I8753@ida.interface-business.de> Message-ID: <20021114104650.T69283-100000@sasami.jurai.net> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org On Thu, 14 Nov 2002, Joerg Wunsch wrote: > Right now, the only way i know to get out of this dilemma is to unplug > the drive again, "camcontrol rescan" so it will be removed completely, > replug it, "camcontrol rescan" so it's known again. I think this is not > quite optimal... Isn't there another way to get the da driver back to > live? IMHO there should be one. Like 'camcontrol detach' or something? ftp://ftp.jurai.net/users/winter/camcontrol-detach.patch There are some issues with it but it works well enough for me. -- | Matthew N. Dodd | '78 Datsun 280Z | '75 Volvo 164E | FreeBSD/NetBSD | | winter@jurai.net | 2 x '84 Volvo 245DL | ix86,sparc,pmax | | http://www.jurai.net/~winter | For Great Justice! | ISO8802.5 4ever | To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Thu Nov 14 8:30:42 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0065437B401 for ; Thu, 14 Nov 2002 08:30:41 -0800 (PST) Received: from ida.interface-business.de (ida.interface-business.de [193.101.57.9]) by mx1.FreeBSD.org (Postfix) with ESMTP id DBDA943E42 for ; Thu, 14 Nov 2002 08:30:39 -0800 (PST) (envelope-from j@ida.interface-business.de) Received: from ida.interface-business.de (localhost [127.0.0.1]) by ida.interface-business.de (8.12.5/8.12.5/ifb) with ESMTP id gAEGUbc6011458; Thu, 14 Nov 2002 17:30:37 +0100 (MET) (envelope-from j@ida.interface-business.de) Received: (from j@localhost) by ida.interface-business.de (8.12.5/8.12.5/Submit) id gAEGUari011457; Thu, 14 Nov 2002 17:30:36 +0100 (MET) (envelope-from j) Date: Thu, 14 Nov 2002 17:30:36 +0100 From: Joerg Wunsch To: "Matthew N. Dodd" Cc: scsi@FreeBSD.ORG Subject: Re: How to recover an invalidated device? Message-ID: <20021114173036.M8753@ida.interface-business.de> Reply-To: Joerg Wunsch Mail-Followup-To: "Matthew N. Dodd" , scsi@FreeBSD.ORG References: <20021114143642.I8753@ida.interface-business.de> <20021114104650.T69283-100000@sasami.jurai.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20021114104650.T69283-100000@sasami.jurai.net>; from winter@jurai.net on Thu, Nov 14, 2002 at 10:51:04AM -0500 X-Phone: +49-351-31809-14 X-PGP-Fingerprint: DC 47 E6 E4 FF A6 E9 8F 93 21 E0 7D F9 12 D6 4E Organization: interface systems GmbH, Dresden Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org As Matthew N. Dodd wrote: > > Right now, the only way i know to get out of this dilemma is to unplug > > the drive again, "camcontrol rescan" so it will be removed completely, > > replug it, "camcontrol rescan" so it's known again. I think this is not > > quite optimal... Isn't there another way to get the da driver back to > > live? IMHO there should be one. > > Like 'camcontrol detach' or something? > > ftp://ftp.jurai.net/users/winter/camcontrol-detach.patch Well, i backported it to RELENG_4 (which isn't much of a problem after also MFCing the changes for camcontrol load and the split of cam_cmd/ cam_arg), and it might /almost/ be what i'm looking for, yes. Anyway: xcd6# camcontrol detach da1 (da1:ahc0:0:6:0): lost device Device detached. xcd6# camcontrol rescan 0:6:0 Re-scan of 0:6:0 was successful xcd6# camcontrol devlist at scbus0 target 0 lun 0 (pass0,da0) at scbus0 target 6 lun 0 (pass1,da1) xcd6# hd /dev/da1h hd: /dev/da1h: Device not configured I think the problem is: cam_periph_alloc: attempt to re-allocate valid device da1 rejected daasync: Unable to attach to new device due to status 0x6 vinum still holds /dev/da1h open, and there's no easy way to tell it to give up about that without either destroying its complete configuration, or unloading vinum, which is both an unreasonable thing to do in a running configuration. So we also need a way to convince CAM that the newly arrived da1 is basically the very same da1 it used to have previously, and it's completely OK to re-use that device. I wish there'd at least be a "force" option or something like that that simply tells CAM "I'm the system administrator, and I tell you to do this since I know what happened, and what I'm doing." -- J"org Wunsch Unix support engineer joerg_wunsch@interface-systems.de http://www.interface-systems.de/~j/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message From owner-freebsd-scsi Fri Nov 15 4:49:31 2002 Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5E98F37B401 for ; Fri, 15 Nov 2002 04:49:17 -0800 (PST) Received: from bast.unixathome.org (bast.unixathome.org [216.187.105.150]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1CAB543E3B for ; Fri, 15 Nov 2002 04:49:15 -0800 (PST) (envelope-from dan@langille.org) Received: from wocker (wocker.unixathome.org [192.168.0.99]) by bast.unixathome.org (Postfix) with ESMTP id D97823F4B for ; Fri, 15 Nov 2002 07:49:03 -0500 (EST) From: "Dan Langille" To: freebsd-scsi@freebsd.org Date: Fri, 15 Nov 2002 07:49:03 -0500 MIME-Version: 1.0 Content-type: Multipart/Mixed; boundary=Message-Boundary-10338 Subject: Re: 4.7 kernel does not find aha1 Message-ID: <3DD4A6EF.31162.9EA9B4A9@localhost> In-reply-to: <20021114163407.Y5562-100000@m20.unixathome.org> X-mailer: Pegasus Mail for Windows (v4.02a) Sender: owner-freebsd-scsi@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org --Message-Boundary-10338 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body This thread was started on -stable. Please see http://docs.freebsd.org/cgi/getmsg.cgi?fetch=402678+0+current/freebsd- stable Attached are: results of a boot -v for the 4.7 kernel results of a boot -v for the 4.6 kernel pciconf -l for the 4.6 kernel Anything I can provide which might be useful? Thanks Attachments: Z:\tmp\4.7-boot-v.txt Z:\tmp\4.6-boot-v.txt Z:\tmp\4.6-pciconf.txt -- Dan Langille : http://www.langille.org/ --Message-Boundary-10338 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Text from file '4.7-boot-v.txt' ok boot -v SMAP type=01 base=00000000 00000000 len=00000000 0009fc00 SMAP type=01 base=00000000 0009fc00 len=00000000 00000400 SMAP type=02 base=00000000 000f0000 len=00000000 00010000 SMAP type=02 base=00000000 ffff0000 len=00000000 00010000 SMAP type=01 base=00000000 00100000 len=00000000 03f00000 Copyright (c) 1992-2002 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD 4.7-STABLE #0: Fri Nov 15 09:44:58 NZDT 2002 dan@cvsup.nz.freebsd.org:/usr/home/ncvs/usr-src/sys/compile/ZEKE Calibrating clock(s) ... TSC clock: 132974131 Hz, i8254 clock: 1193359 Hz CLK_USE_I8254_CALIBRATION not specified - using default frequency Timecounter "i8254" frequency 1193182 Hz CLK_USE_TSC_CALIBRATION not specified - using old calibration method CPU: Pentium/P54C (132.95-MHz 586-class CPU) Origin = "GenuineIntel" Id = 0x52c Stepping = 12 Features=0x1bf real memory = 67108864 (65536K bytes) Physical memory chunk(s): 0x00001000 - 0x0009ffff, 651264 bytes (159 pages) 0x00506000 - 0x03ff7fff, 61808640 bytes (15090 pages) kbdc: DIAGNOSE status:0055 kbdc: TEST_KBD_PORT status:0000 kbdc: DIAGNOSE status:0055 kbdc: TEST_KBD_PORT status:0000 avail memory = 60383232 (58968K bytes) bios32: Found BIOS32 Service Directory header at 0xc00fae70 bios32: Entry = 0xfb270 (c00fb270) Rev = 0 Len = 1 pcibios: PCI BIOS entry at 0xb2a0 pnpbios: Found PnP BIOS data at 0xc00fbf90 pnpbios: Entry = f0000:bfb8 Rev = 1.0 Other BIOS signatures found: ACPI: 00000000 Preloaded elf kernel "kernel" at 0xc04df000. Intel Pentium detected, installing workaround for F00F bug Creating DISK md0 md0: Malloc disk Math emulator present pci_open(1): mode 1 addr port (0x0cf8) is 0x8000005c pci_open(1a): mode1res=0x80000000 (0x80000000) pci_cfgcheck: device 0 [class=060000] [hdr=00] is there (id=12508086) npx0: on motherboard npx0: INT 16 interface i586_bzero() bandwidth = 130225289 bytes/sec bzero() bandwidth = 736919675 bytes/sec pcib0: on motherboard found-> vendor=0x8086, dev=0x1250, revid=0x03 class=06-00-00, hdrtype=0x00, mfdev=0 subordinatebus=0 secondarybus=0 found-> vendor=0x8086, dev=0x7000, revid=0x01 class=06-01-00, hdrtype=0x00, mfdev=1 subordinatebus=0 secondarybus=0 found-> vendor=0x8086, dev=0x7010, revid=0x00 class=01-01-80, hdrtype=0x00, mfdev=0 subordinatebus=0 secondarybus=0 map[20]: type 1, range 32, base 0000f000, size 4 found-> vendor=0x8086, dev=0x1229, revid=0x01 class=02-00-00, hdrtype=0x00, mfdev=0 subordinatebus=0 secondarybus=0 intpin=a, irq=15 map[10]: type 1, range 32, base e1100000, size 12 map[14]: type 1, range 32, base 00006100, size 5 map[18]: type 1, range 32, base e1000000, size 20 found-> vendor=0x1013, dev=0x00a8, revid=0xf9 class=03-00-00, hdrtype=0x00, mfdev=0 subordinatebus=0 secondarybus=0 map[10]: type 1, range 32, base e0000000, size 24 pci0: on pcib0 isab0: at device 7.0 on pci0 I/O Recovery Timing: 8-bit 1 clocks, 16-bit 1 clocks Extended BIOS: disabled Lower BIOS: disabled Coprocessor IRQ13: enabled Mouse IRQ12: disabled Interrupt Routing: A: disabled, B: IRQ15, C: disabled, D: disabled MB0: disabled, MB1: isa0: on isab0 atapci0: port 0xf000-0xf00f at device 7.1 on pci0 ata0: iobase=0x01f0 altiobase=0x03f6 bmaddr=0xf000 ata0: mask=03 ostat0=50 ostat2=00 ata0-master: ATAPI 00 00 ata0-slave: ATAPI 00 00 ata0: mask=03 stat0=50 stat1=00 ata0-master: ATA 01 a5 ata0: devices=01 ata0: at 0x1f0 irq 14 on atapci0 ata1: iobase=0x0170 altiobase=0x0376 bmaddr=0xf008 ata1: at 0x170 irq 15 on atapci0 fxp0: port 0x6100-0x611f mem 0xe1000000-0xe10f ffff,0xe1100000-0xe1100fff irq 15 at device 18.0 on pci0 fxp0: using memory space register mapping using shared irq15. fxp0: Ethernet address 00:a0:c9:16:d5:60, 10Mbps fxp0: PCI IDs: 8086 1229 0000 0000 0001 fxp0: Dynamic Standby mode is disabled bpf: fxp0 attached pci0: (vendor=0x1013, dev=0x00a8) at 19.0 ex_isa_identify() ata-: ata0 exists, using next available unit number ata-: ata1 exists, using next available unit number Trying Read_Port at 203 ADP1542: adding irq mask 0xdc00 ADP1542: adding dma mask 0xe0 ADP1542: start dependant ADP1542: adding io range 0x330-0x333, size=0x4, align=0x4 ADP1542: start dependant ADP1542: adding io range 0x334-0x337, size=0x4, align=0x4 ADP1542: start dependant ADP1542: adding io range 0x234-0x237, size=0x4, align=0x4 ADP1542: start dependant ADP1542: adding io range 0x230-0x233, size=0x4, align=0x4 ADP1542: start dependant ADP1542: adding io range 0x134-0x137, size=0x4, align=0x4 ADP1542: start dependant ADP1542: adding io range 0x130-0x133, size=0x4, align=0x4 ADP1542: end dependant ADP1542: adding memory range 0xc8000-0xdffff, size=0x4000, align=0x4000 isa_probe_children: disabling PnP devices isa_probe_children: probing non-PnP devices orm0: