| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rf_netbsdkintf.c,v 1.265 2009/06/10 14:17:13 pooka Exp $ */ | | 1 | /* $NetBSD: rf_netbsdkintf.c,v 1.266 2009/07/23 21:58:06 dyoung Exp $ */ |
2 | /*- | | 2 | /*- |
3 | * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc. | | 3 | * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc. |
4 | * All rights reserved. | | 4 | * All rights reserved. |
5 | * | | 5 | * |
6 | * This code is derived from software contributed to The NetBSD Foundation | | 6 | * This code is derived from software contributed to The NetBSD Foundation |
7 | * by Greg Oster; Jason R. Thorpe. | | 7 | * by Greg Oster; Jason R. Thorpe. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -129,27 +129,27 @@ | | | @@ -129,27 +129,27 @@ |
129 | * Pittsburgh PA 15213-3890 | | 129 | * Pittsburgh PA 15213-3890 |
130 | * | | 130 | * |
131 | * any improvements or extensions that they make and grant Carnegie the | | 131 | * any improvements or extensions that they make and grant Carnegie the |
132 | * rights to redistribute these changes. | | 132 | * rights to redistribute these changes. |
133 | */ | | 133 | */ |
134 | | | 134 | |
135 | /*********************************************************** | | 135 | /*********************************************************** |
136 | * | | 136 | * |
137 | * rf_kintf.c -- the kernel interface routines for RAIDframe | | 137 | * rf_kintf.c -- the kernel interface routines for RAIDframe |
138 | * | | 138 | * |
139 | ***********************************************************/ | | 139 | ***********************************************************/ |
140 | | | 140 | |
141 | #include <sys/cdefs.h> | | 141 | #include <sys/cdefs.h> |
142 | __KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.265 2009/06/10 14:17:13 pooka Exp $"); | | 142 | __KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.266 2009/07/23 21:58:06 dyoung Exp $"); |
143 | | | 143 | |
144 | #ifdef _KERNEL_OPT | | 144 | #ifdef _KERNEL_OPT |
145 | #include "opt_compat_netbsd.h" | | 145 | #include "opt_compat_netbsd.h" |
146 | #include "opt_raid_autoconfig.h" | | 146 | #include "opt_raid_autoconfig.h" |
147 | #include "raid.h" | | 147 | #include "raid.h" |
148 | #endif | | 148 | #endif |
149 | | | 149 | |
150 | #include <sys/param.h> | | 150 | #include <sys/param.h> |
151 | #include <sys/errno.h> | | 151 | #include <sys/errno.h> |
152 | #include <sys/pool.h> | | 152 | #include <sys/pool.h> |
153 | #include <sys/proc.h> | | 153 | #include <sys/proc.h> |
154 | #include <sys/queue.h> | | 154 | #include <sys/queue.h> |
155 | #include <sys/disk.h> | | 155 | #include <sys/disk.h> |
| @@ -250,35 +250,37 @@ static struct dkdriver rf_dkdriver = { r | | | @@ -250,35 +250,37 @@ static struct dkdriver rf_dkdriver = { r |
250 | struct raid_softc { | | 250 | struct raid_softc { |
251 | device_t sc_dev; | | 251 | device_t sc_dev; |
252 | int sc_flags; /* flags */ | | 252 | int sc_flags; /* flags */ |
253 | int sc_cflags; /* configuration flags */ | | 253 | int sc_cflags; /* configuration flags */ |
254 | uint64_t sc_size; /* size of the raid device */ | | 254 | uint64_t sc_size; /* size of the raid device */ |
255 | char sc_xname[20]; /* XXX external name */ | | 255 | char sc_xname[20]; /* XXX external name */ |
256 | struct disk sc_dkdev; /* generic disk device info */ | | 256 | struct disk sc_dkdev; /* generic disk device info */ |
257 | struct bufq_state *buf_queue; /* used for the device queue */ | | 257 | struct bufq_state *buf_queue; /* used for the device queue */ |
258 | }; | | 258 | }; |
259 | /* sc_flags */ | | 259 | /* sc_flags */ |
260 | #define RAIDF_INITED 0x01 /* unit has been initialized */ | | 260 | #define RAIDF_INITED 0x01 /* unit has been initialized */ |
261 | #define RAIDF_WLABEL 0x02 /* label area is writable */ | | 261 | #define RAIDF_WLABEL 0x02 /* label area is writable */ |
262 | #define RAIDF_LABELLING 0x04 /* unit is currently being labelled */ | | 262 | #define RAIDF_LABELLING 0x04 /* unit is currently being labelled */ |
| | | 263 | #define RAIDF_SHUTDOWN 0x08 /* unit is being shutdown */ |
263 | #define RAIDF_WANTED 0x40 /* someone is waiting to obtain a lock */ | | 264 | #define RAIDF_WANTED 0x40 /* someone is waiting to obtain a lock */ |
264 | #define RAIDF_LOCKED 0x80 /* unit is locked */ | | 265 | #define RAIDF_LOCKED 0x80 /* unit is locked */ |
265 | | | 266 | |
266 | #define raidunit(x) DISKUNIT(x) | | 267 | #define raidunit(x) DISKUNIT(x) |
267 | int numraid = 0; | | 268 | int numraid = 0; |
268 | | | 269 | |
269 | extern struct cfdriver raid_cd; | | 270 | extern struct cfdriver raid_cd; |
270 | CFATTACH_DECL_NEW(raid, sizeof(struct raid_softc), | | 271 | CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc), |
271 | raid_match, raid_attach, raid_detach, NULL); | | 272 | raid_match, raid_attach, raid_detach, NULL, NULL, NULL, |
| | | 273 | DVF_DETACH_SHUTDOWN); |
272 | | | 274 | |
273 | /* | | 275 | /* |
274 | * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device. | | 276 | * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device. |
275 | * Be aware that large numbers can allow the driver to consume a lot of | | 277 | * Be aware that large numbers can allow the driver to consume a lot of |
276 | * kernel memory, especially on writes, and in degraded mode reads. | | 278 | * kernel memory, especially on writes, and in degraded mode reads. |
277 | * | | 279 | * |
278 | * For example: with a stripe width of 64 blocks (32k) and 5 disks, | | 280 | * For example: with a stripe width of 64 blocks (32k) and 5 disks, |
279 | * a single 64K write will typically require 64K for the old data, | | 281 | * a single 64K write will typically require 64K for the old data, |
280 | * 64K for the old parity, and 64K for the new parity, for a total | | 282 | * 64K for the old parity, and 64K for the new parity, for a total |
281 | * of 192K (if the parity buffer is not re-used immediately). | | 283 | * of 192K (if the parity buffer is not re-used immediately). |
282 | * Even it if is used immediately, that's still 128K, which when multiplied | | 284 | * Even it if is used immediately, that's still 128K, which when multiplied |
283 | * by say 10 requests, is 1280K, *on top* of the 640K of incoming data. | | 285 | * by say 10 requests, is 1280K, *on top* of the 640K of incoming data. |
284 | * | | 286 | * |
| @@ -295,26 +297,28 @@ CFATTACH_DECL_NEW(raid, sizeof(struct ra | | | @@ -295,26 +297,28 @@ CFATTACH_DECL_NEW(raid, sizeof(struct ra |
295 | (MAKEDISKDEV(major((dev)), raidunit((dev)), RAW_PART)) | | 297 | (MAKEDISKDEV(major((dev)), raidunit((dev)), RAW_PART)) |
296 | | | 298 | |
297 | /* declared here, and made public, for the benefit of KVM stuff.. */ | | 299 | /* declared here, and made public, for the benefit of KVM stuff.. */ |
298 | struct raid_softc *raid_softc; | | 300 | struct raid_softc *raid_softc; |
299 | | | 301 | |
300 | static void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *, | | 302 | static void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *, |
301 | struct disklabel *); | | 303 | struct disklabel *); |
302 | static void raidgetdisklabel(dev_t); | | 304 | static void raidgetdisklabel(dev_t); |
303 | static void raidmakedisklabel(struct raid_softc *); | | 305 | static void raidmakedisklabel(struct raid_softc *); |
304 | | | 306 | |
305 | static int raidlock(struct raid_softc *); | | 307 | static int raidlock(struct raid_softc *); |
306 | static void raidunlock(struct raid_softc *); | | 308 | static void raidunlock(struct raid_softc *); |
307 | | | 309 | |
| | | 310 | static int raid_detach_unlocked(struct raid_softc *); |
| | | 311 | |
308 | static void rf_markalldirty(RF_Raid_t *); | | 312 | static void rf_markalldirty(RF_Raid_t *); |
309 | static void rf_set_properties(struct raid_softc *, RF_Raid_t *); | | 313 | static void rf_set_properties(struct raid_softc *, RF_Raid_t *); |
310 | | | 314 | |
311 | void rf_ReconThread(struct rf_recon_req *); | | 315 | void rf_ReconThread(struct rf_recon_req *); |
312 | void rf_RewriteParityThread(RF_Raid_t *raidPtr); | | 316 | void rf_RewriteParityThread(RF_Raid_t *raidPtr); |
313 | void rf_CopybackThread(RF_Raid_t *raidPtr); | | 317 | void rf_CopybackThread(RF_Raid_t *raidPtr); |
314 | void rf_ReconstructInPlaceThread(struct rf_recon_req *); | | 318 | void rf_ReconstructInPlaceThread(struct rf_recon_req *); |
315 | int rf_autoconfig(device_t); | | 319 | int rf_autoconfig(device_t); |
316 | void rf_buildroothack(RF_ConfigSet_t *); | | 320 | void rf_buildroothack(RF_ConfigSet_t *); |
317 | | | 321 | |
318 | RF_AutoConfig_t *rf_find_raid_components(void); | | 322 | RF_AutoConfig_t *rf_find_raid_components(void); |
319 | RF_ConfigSet_t *rf_create_auto_sets(RF_AutoConfig_t *); | | 323 | RF_ConfigSet_t *rf_create_auto_sets(RF_AutoConfig_t *); |
320 | static int rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *); | | 324 | static int rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *); |
| @@ -719,26 +723,32 @@ raidopen(dev_t dev, int flags, int fmt, | | | @@ -719,26 +723,32 @@ raidopen(dev_t dev, int flags, int fmt, |
719 | { | | 723 | { |
720 | int unit = raidunit(dev); | | 724 | int unit = raidunit(dev); |
721 | struct raid_softc *rs; | | 725 | struct raid_softc *rs; |
722 | struct disklabel *lp; | | 726 | struct disklabel *lp; |
723 | int part, pmask; | | 727 | int part, pmask; |
724 | int error = 0; | | 728 | int error = 0; |
725 | | | 729 | |
726 | if (unit >= numraid) | | 730 | if (unit >= numraid) |
727 | return (ENXIO); | | 731 | return (ENXIO); |
728 | rs = &raid_softc[unit]; | | 732 | rs = &raid_softc[unit]; |
729 | | | 733 | |
730 | if ((error = raidlock(rs)) != 0) | | 734 | if ((error = raidlock(rs)) != 0) |
731 | return (error); | | 735 | return (error); |
| | | 736 | |
| | | 737 | if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0) { |
| | | 738 | error = EBUSY; |
| | | 739 | goto bad; |
| | | 740 | } |
| | | 741 | |
732 | lp = rs->sc_dkdev.dk_label; | | 742 | lp = rs->sc_dkdev.dk_label; |
733 | | | 743 | |
734 | part = DISKPART(dev); | | 744 | part = DISKPART(dev); |
735 | | | 745 | |
736 | /* | | 746 | /* |
737 | * If there are wedges, and this is not RAW_PART, then we | | 747 | * If there are wedges, and this is not RAW_PART, then we |
738 | * need to fail. | | 748 | * need to fail. |
739 | */ | | 749 | */ |
740 | if (rs->sc_dkdev.dk_nwedges != 0 && part != RAW_PART) { | | 750 | if (rs->sc_dkdev.dk_nwedges != 0 && part != RAW_PART) { |
741 | error = EBUSY; | | 751 | error = EBUSY; |
742 | goto bad; | | 752 | goto bad; |
743 | } | | 753 | } |
744 | pmask = (1 << part); | | 754 | pmask = (1 << part); |
| @@ -787,27 +797,26 @@ raidopen(dev_t dev, int flags, int fmt, | | | @@ -787,27 +797,26 @@ raidopen(dev_t dev, int flags, int fmt, |
787 | | | 797 | |
788 | bad: | | 798 | bad: |
789 | raidunlock(rs); | | 799 | raidunlock(rs); |
790 | | | 800 | |
791 | return (error); | | 801 | return (error); |
792 | | | 802 | |
793 | | | 803 | |
794 | } | | 804 | } |
795 | /* ARGSUSED */ | | 805 | /* ARGSUSED */ |
796 | int | | 806 | int |
797 | raidclose(dev_t dev, int flags, int fmt, struct lwp *l) | | 807 | raidclose(dev_t dev, int flags, int fmt, struct lwp *l) |
798 | { | | 808 | { |
799 | int unit = raidunit(dev); | | 809 | int unit = raidunit(dev); |
800 | cfdata_t cf; | | | |
801 | struct raid_softc *rs; | | 810 | struct raid_softc *rs; |
802 | int error = 0; | | 811 | int error = 0; |
803 | int part; | | 812 | int part; |
804 | | | 813 | |
805 | if (unit >= numraid) | | 814 | if (unit >= numraid) |
806 | return (ENXIO); | | 815 | return (ENXIO); |
807 | rs = &raid_softc[unit]; | | 816 | rs = &raid_softc[unit]; |
808 | | | 817 | |
809 | if ((error = raidlock(rs)) != 0) | | 818 | if ((error = raidlock(rs)) != 0) |
810 | return (error); | | 819 | return (error); |
811 | | | 820 | |
812 | part = DISKPART(dev); | | 821 | part = DISKPART(dev); |
813 | | | 822 | |
| @@ -823,44 +832,30 @@ raidclose(dev_t dev, int flags, int fmt, | | | @@ -823,44 +832,30 @@ raidclose(dev_t dev, int flags, int fmt, |
823 | } | | 832 | } |
824 | rs->sc_dkdev.dk_openmask = | | 833 | rs->sc_dkdev.dk_openmask = |
825 | rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask; | | 834 | rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask; |
826 | | | 835 | |
827 | if ((rs->sc_dkdev.dk_openmask == 0) && | | 836 | if ((rs->sc_dkdev.dk_openmask == 0) && |
828 | ((rs->sc_flags & RAIDF_INITED) != 0)) { | | 837 | ((rs->sc_flags & RAIDF_INITED) != 0)) { |
829 | /* Last one... device is not unconfigured yet. | | 838 | /* Last one... device is not unconfigured yet. |
830 | Device shutdown has taken care of setting the | | 839 | Device shutdown has taken care of setting the |
831 | clean bits if RAIDF_INITED is not set | | 840 | clean bits if RAIDF_INITED is not set |
832 | mark things as clean... */ | | 841 | mark things as clean... */ |
833 | | | 842 | |
834 | rf_update_component_labels(raidPtrs[unit], | | 843 | rf_update_component_labels(raidPtrs[unit], |
835 | RF_FINAL_COMPONENT_UPDATE); | | 844 | RF_FINAL_COMPONENT_UPDATE); |
836 | if (doing_shutdown) { | | | |
837 | /* last one, and we're going down, so | | | |
838 | lights out for this RAID set too. */ | | | |
839 | error = rf_Shutdown(raidPtrs[unit]); | | | |
840 | | | | |
841 | /* It's no longer initialized... */ | | | |
842 | rs->sc_flags &= ~RAIDF_INITED; | | | |
843 | | | 845 | |
844 | /* detach the device */ | | 846 | /* If the kernel is shutting down, it will detach |
845 | | | 847 | * this RAID set soon enough. |
846 | cf = device_cfdata(rs->sc_dev); | | 848 | */ |
847 | error = config_detach(rs->sc_dev, DETACH_QUIET); | | | |
848 | free(cf, M_RAIDFRAME); | | | |
849 | | | | |
850 | /* Detach the disk. */ | | | |
851 | disk_detach(&rs->sc_dkdev); | | | |
852 | disk_destroy(&rs->sc_dkdev); | | | |
853 | } | | | |
854 | } | | 849 | } |
855 | | | 850 | |
856 | raidunlock(rs); | | 851 | raidunlock(rs); |
857 | return (0); | | 852 | return (0); |
858 | | | 853 | |
859 | } | | 854 | } |
860 | | | 855 | |
861 | void | | 856 | void |
862 | raidstrategy(struct buf *bp) | | 857 | raidstrategy(struct buf *bp) |
863 | { | | 858 | { |
864 | int s; | | 859 | int s; |
865 | | | 860 | |
866 | unsigned int raidID = raidunit(bp->b_dev); | | 861 | unsigned int raidID = raidunit(bp->b_dev); |
| @@ -954,26 +949,55 @@ raidwrite(dev_t dev, struct uio *uio, in | | | @@ -954,26 +949,55 @@ raidwrite(dev_t dev, struct uio *uio, in |
954 | struct raid_softc *rs; | | 949 | struct raid_softc *rs; |
955 | | | 950 | |
956 | if (unit >= numraid) | | 951 | if (unit >= numraid) |
957 | return (ENXIO); | | 952 | return (ENXIO); |
958 | rs = &raid_softc[unit]; | | 953 | rs = &raid_softc[unit]; |
959 | | | 954 | |
960 | if ((rs->sc_flags & RAIDF_INITED) == 0) | | 955 | if ((rs->sc_flags & RAIDF_INITED) == 0) |
961 | return (ENXIO); | | 956 | return (ENXIO); |
962 | | | 957 | |
963 | return (physio(raidstrategy, NULL, dev, B_WRITE, minphys, uio)); | | 958 | return (physio(raidstrategy, NULL, dev, B_WRITE, minphys, uio)); |
964 | | | 959 | |
965 | } | | 960 | } |
966 | | | 961 | |
| | | 962 | static int |
| | | 963 | raid_detach_unlocked(struct raid_softc *rs) |
| | | 964 | { |
| | | 965 | int error; |
| | | 966 | RF_Raid_t *raidPtr; |
| | | 967 | |
| | | 968 | raidPtr = raidPtrs[device_unit(rs->sc_dev)]; |
| | | 969 | |
| | | 970 | /* |
| | | 971 | * If somebody has a partition mounted, we shouldn't |
| | | 972 | * shutdown. |
| | | 973 | */ |
| | | 974 | if (rs->sc_dkdev.dk_openmask != 0) |
| | | 975 | return EBUSY; |
| | | 976 | |
| | | 977 | if ((rs->sc_flags & RAIDF_INITED) == 0) |
| | | 978 | ; /* not initialized: nothing to do */ |
| | | 979 | else if ((error = rf_Shutdown(raidPtr)) != 0) |
| | | 980 | return error; |
| | | 981 | else |
| | | 982 | rs->sc_flags &= ~(RAIDF_INITED|RAIDF_SHUTDOWN); |
| | | 983 | |
| | | 984 | /* Detach the disk. */ |
| | | 985 | disk_detach(&rs->sc_dkdev); |
| | | 986 | disk_destroy(&rs->sc_dkdev); |
| | | 987 | |
| | | 988 | return 0; |
| | | 989 | } |
| | | 990 | |
967 | int | | 991 | int |
968 | raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) | | 992 | raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) |
969 | { | | 993 | { |
970 | int unit = raidunit(dev); | | 994 | int unit = raidunit(dev); |
971 | int error = 0; | | 995 | int error = 0; |
972 | int part, pmask; | | 996 | int part, pmask; |
973 | cfdata_t cf; | | 997 | cfdata_t cf; |
974 | struct raid_softc *rs; | | 998 | struct raid_softc *rs; |
975 | RF_Config_t *k_cfg, *u_cfg; | | 999 | RF_Config_t *k_cfg, *u_cfg; |
976 | RF_Raid_t *raidPtr; | | 1000 | RF_Raid_t *raidPtr; |
977 | RF_RaidDisk_t *diskPtr; | | 1001 | RF_RaidDisk_t *diskPtr; |
978 | RF_AccTotals_t *totals; | | 1002 | RF_AccTotals_t *totals; |
979 | RF_DeviceConfig_t *d_cfg, **ucfgp; | | 1003 | RF_DeviceConfig_t *d_cfg, **ucfgp; |
| @@ -1163,61 +1187,54 @@ raidioctl(dev_t dev, u_long cmd, void *d | | | @@ -1163,61 +1187,54 @@ raidioctl(dev_t dev, u_long cmd, void *d |
1163 | rf_markalldirty(raidPtr); | | 1187 | rf_markalldirty(raidPtr); |
1164 | } | | 1188 | } |
1165 | /* free the buffers. No return code here. */ | | 1189 | /* free the buffers. No return code here. */ |
1166 | if (k_cfg->layoutSpecificSize) { | | 1190 | if (k_cfg->layoutSpecificSize) { |
1167 | RF_Free(specific_buf, k_cfg->layoutSpecificSize); | | 1191 | RF_Free(specific_buf, k_cfg->layoutSpecificSize); |
1168 | } | | 1192 | } |
1169 | RF_Free(k_cfg, sizeof(RF_Config_t)); | | 1193 | RF_Free(k_cfg, sizeof(RF_Config_t)); |
1170 | | | 1194 | |
1171 | return (retcode); | | 1195 | return (retcode); |
1172 | | | 1196 | |
1173 | /* shutdown the system */ | | 1197 | /* shutdown the system */ |
1174 | case RAIDFRAME_SHUTDOWN: | | 1198 | case RAIDFRAME_SHUTDOWN: |
1175 | | | 1199 | |
| | | 1200 | part = DISKPART(dev); |
| | | 1201 | pmask = (1 << part); |
| | | 1202 | |
1176 | if ((error = raidlock(rs)) != 0) | | 1203 | if ((error = raidlock(rs)) != 0) |
1177 | return (error); | | 1204 | return (error); |
1178 | | | 1205 | |
1179 | /* | | | |
1180 | * If somebody has a partition mounted, we shouldn't | | | |
1181 | * shutdown. | | | |
1182 | */ | | | |
1183 | | | | |
1184 | part = DISKPART(dev); | | | |
1185 | pmask = (1 << part); | | | |
1186 | if ((rs->sc_dkdev.dk_openmask & ~pmask) || | | 1206 | if ((rs->sc_dkdev.dk_openmask & ~pmask) || |
1187 | ((rs->sc_dkdev.dk_bopenmask & pmask) && | | 1207 | ((rs->sc_dkdev.dk_bopenmask & pmask) && |
1188 | (rs->sc_dkdev.dk_copenmask & pmask))) { | | 1208 | (rs->sc_dkdev.dk_copenmask & pmask))) |
1189 | raidunlock(rs); | | 1209 | retcode = EBUSY; |
1190 | return (EBUSY); | | 1210 | else { |
| | | 1211 | rs->sc_flags |= RAIDF_SHUTDOWN; |
| | | 1212 | rs->sc_dkdev.dk_copenmask &= ~pmask; |
| | | 1213 | rs->sc_dkdev.dk_bopenmask &= ~pmask; |
| | | 1214 | rs->sc_dkdev.dk_openmask &= ~pmask; |
| | | 1215 | retcode = 0; |
1191 | } | | 1216 | } |
1192 | | | 1217 | |
1193 | retcode = rf_Shutdown(raidPtr); | | 1218 | raidunlock(rs); |
1194 | | | 1219 | |
1195 | /* It's no longer initialized... */ | | 1220 | if (retcode != 0) |
1196 | rs->sc_flags &= ~RAIDF_INITED; | | 1221 | return retcode; |
1197 | | | 1222 | |
1198 | /* free the pseudo device attach bits */ | | 1223 | /* free the pseudo device attach bits */ |
1199 | | | 1224 | |
1200 | cf = device_cfdata(rs->sc_dev); | | 1225 | cf = device_cfdata(rs->sc_dev); |
1201 | /* XXX this causes us to not return any errors | | 1226 | if ((retcode = config_detach(rs->sc_dev, DETACH_QUIET)) == 0) |
1202 | from the above call to rf_Shutdown() */ | | 1227 | free(cf, M_RAIDFRAME); |
1203 | retcode = config_detach(rs->sc_dev, DETACH_QUIET); | | | |
1204 | free(cf, M_RAIDFRAME); | | | |
1205 | | | | |
1206 | /* Detach the disk. */ | | | |
1207 | disk_detach(&rs->sc_dkdev); | | | |
1208 | disk_destroy(&rs->sc_dkdev); | | | |
1209 | | | | |
1210 | raidunlock(rs); | | | |
1211 | | | 1228 | |
1212 | return (retcode); | | 1229 | return (retcode); |
1213 | case RAIDFRAME_GET_COMPONENT_LABEL: | | 1230 | case RAIDFRAME_GET_COMPONENT_LABEL: |
1214 | clabel_ptr = (RF_ComponentLabel_t **) data; | | 1231 | clabel_ptr = (RF_ComponentLabel_t **) data; |
1215 | /* need to read the component label for the disk indicated | | 1232 | /* need to read the component label for the disk indicated |
1216 | by row,column in clabel */ | | 1233 | by row,column in clabel */ |
1217 | | | 1234 | |
1218 | /* For practice, let's get it directly fromdisk, rather | | 1235 | /* For practice, let's get it directly fromdisk, rather |
1219 | than from the in-core copy */ | | 1236 | than from the in-core copy */ |
1220 | RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ), | | 1237 | RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ), |
1221 | (RF_ComponentLabel_t *)); | | 1238 | (RF_ComponentLabel_t *)); |
1222 | if (clabel == NULL) | | 1239 | if (clabel == NULL) |
1223 | return (ENOMEM); | | 1240 | return (ENOMEM); |
| @@ -3610,32 +3627,37 @@ raid_match(device_t self, cfdata_t cfdat | | | @@ -3610,32 +3627,37 @@ raid_match(device_t self, cfdata_t cfdat |
3610 | return 1; | | 3627 | return 1; |
3611 | } | | 3628 | } |
3612 | | | 3629 | |
3613 | static void | | 3630 | static void |
3614 | raid_attach(device_t parent, device_t self, void *aux) | | 3631 | raid_attach(device_t parent, device_t self, void *aux) |
3615 | { | | 3632 | { |
3616 | | | 3633 | |
3617 | } | | 3634 | } |
3618 | | | 3635 | |
3619 | | | 3636 | |
3620 | static int | | 3637 | static int |
3621 | raid_detach(device_t self, int flags) | | 3638 | raid_detach(device_t self, int flags) |
3622 | { | | 3639 | { |
3623 | struct raid_softc *rs = device_private(self); | | 3640 | int error; |
| | | 3641 | struct raid_softc *rs = &raid_softc[device_unit(self)]; |
3624 | | | 3642 | |
3625 | if (rs->sc_flags & RAIDF_INITED) | | 3643 | if ((error = raidlock(rs)) != 0) |
3626 | return EBUSY; | | 3644 | return (error); |
3627 | | | 3645 | |
3628 | return 0; | | 3646 | error = raid_detach_unlocked(rs); |
| | | 3647 | |
| | | 3648 | raidunlock(rs); |
| | | 3649 | |
| | | 3650 | return error; |
3629 | } | | 3651 | } |
3630 | | | 3652 | |
3631 | static void | | 3653 | static void |
3632 | rf_set_properties(struct raid_softc *rs, RF_Raid_t *raidPtr) | | 3654 | rf_set_properties(struct raid_softc *rs, RF_Raid_t *raidPtr) |
3633 | { | | 3655 | { |
3634 | prop_dictionary_t disk_info, odisk_info, geom; | | 3656 | prop_dictionary_t disk_info, odisk_info, geom; |
3635 | disk_info = prop_dictionary_create(); | | 3657 | disk_info = prop_dictionary_create(); |
3636 | geom = prop_dictionary_create(); | | 3658 | geom = prop_dictionary_create(); |
3637 | prop_dictionary_set_uint64(geom, "sectors-per-unit", | | 3659 | prop_dictionary_set_uint64(geom, "sectors-per-unit", |
3638 | raidPtr->totalSectors); | | 3660 | raidPtr->totalSectors); |
3639 | prop_dictionary_set_uint32(geom, "sector-size", | | 3661 | prop_dictionary_set_uint32(geom, "sector-size", |
3640 | raidPtr->bytesPerSector); | | 3662 | raidPtr->bytesPerSector); |
3641 | | | 3663 | |